Go: package main

import (
	"bytes"
	"fmt"
)

//Ktai has a keyboard and a state.
type Ktai struct {
	keyboard KeyBoard
	textBuf  *bytes.Buffer
}

// KeyBoard is type of a map.
type KeyBoard map[rune]string

// KEYBOARD that Ktai has
var KEYBOARD = KeyBoard{
	'0': "",
	'1': ".,!? ",
	'2': "abc",
	'3': "def",
	'4': "ghi",
	'5': "jkl",
	'6': "mno",
	'7': "pqrs",
	'8': "tuv",
	'9': "wxyz",
}

func main() {
	var N int
	fmt.Scanf("%d", &N)
	ktai := &Ktai{
		KEYBOARD, &bytes.Buffer{},
	}
	for i := 0; i < N; i++ {
		var numstr string
		fmt.Scanf("%s", &numstr)
		ktai.feed(numstr)
		ktai.print()
	}
}

func (ktai *Ktai) feed(str string) {
	var char *byte
	for _, v := range str {
		if v == '0' {
			if char != nil {
				ktai.textBuf.WriteByte(*char)
				char = nil
			}
			continue
		} else {
			runestring := ktai.keyboard[v]
			idx := ktai.indexOf(char, runestring)
			next := (idx + 1) % len(runestring)
			c := runestring[next]
			char = &c
		}
	}
}

func (ktai *Ktai) indexOf(ch *byte, str string) int {
	if ch == nil {
		return -1
	}
	r := rune(*ch)
	idx := -1
	for i, v := range str {
		if r == v {
			idx = i
			break
		}
	}
	return idx
}

func (ktai *Ktai) print() {
	fmt.Println(ktai.textBuf.String())
	ktai.textBuf.Reset()
}

C++: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>

#define FOR(i,k,n) for (int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)

using namespace std;

const int INF = 1000000000;
const double eps = 1e-8;

int main(void) {
  string tb[] = {"",".,!? ","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
  int sz[]={0,5,3,3,3,3,3,4,3,4};
  int n;cin>>n;
  REP(i,n){
    string s;
    cin>>s;
    int cnt = 0;
    int ochar = 0;
    REP(j,s.size()){
      if(s[j]=='0'){
        if(ochar!=0)
          cout<<tb[ochar][cnt%sz[ochar]];
        ochar = 0;
        cnt=0;
      }else{
        if(ochar==(s[j]-'0'))
          cnt++;
        else{
          cnt=0;
          ochar=s[j]-'0';
        }
      }
    }
    cout<<endl;
  }
  return 0;
}

C++: #include <iostream>
#include <string>
#include <vector>
using namespace std;
typedef long long int lli;

string charset[10][5] = {
	{},
	{".", ",", "!", "?", " "},
	{"a", "b", "c"},
	{"d", "e", "f"},
	{"g", "h", "i"},
	{"j", "k", "l"},
	{"m", "n", "o"},
	{"p", "q", "r", "s"},
	{"t", "u", "v"},
	{"w", "x", "y", "z"}
};
int loop[10] = {0, 5, 3, 3, 3, 3, 3, 4, 3, 4};

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);

	int N;
	cin >> N;
	for (int n = 0; n < N; n++){
		string s;
		cin >> s;

		int i = 0;
		int push = -1;
		string ans = "";
		while (i < s.length()){
			int num = stoi(s.substr(i, 1));
			if (num != 0){
				int thisnum = num;
				while (num != 0){
					push++;
					i++;
					num = stoi(s.substr(i, 1));
				}
				ans += charset[thisnum][push % loop[thisnum]];
				push = -1;
			}
			i++;
		}
		cout << ans << endl;
	}

	return 0;
}

C++: #include <iostream>
#include <string>
#include <vector>
using namespace std;

int main(void){
  int n, i, cnt;
  string str, ans;
  char init;
  vector<string> mp{"", ".,!? ","abc","def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
  cin >> n;
  while(n--){
    cin >> str;
    cout << str << endl;
    ans = "";
    i = 0;
    while(i < str.length()){
      while(str[i] == '0'){
        i++;
      }
      if(i >= str.length()){
        break;
      }
      init = str[i];
      cnt = 0;
      while(i < str.length() and str[i] == init){
        i++;
        cnt++;
      }
      ans += mp[init - '0'][(cnt - 1) % mp[init - '0'].length()];
    }
    cout << ans << endl;
  }
  return 0;
}

C++: #include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(){
  string key[10]={"0",".,!? ","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
  int n;
  cin>>n;
  for (int nn=0;nn<n;nn++){
    string in;
    vector<int> input;
    string ans;
    cin>>in;
    for (int i=0;i<in.length();i++){
      input.push_back(in[i]-48);
    }
    int count=0;
    int cc=0;
    for (int i=0;i<in.length();i++){
      if (input[i]==0&&i!=0&&count!=0){
	char c=key[input[i-1]][(count-1)%key[input[i-1]].size()];
	ans[cc]=c;
	cc++;
	count=0;
	continue;
      }
      else if (input[i]==0&&i==0)
	continue;
      else if (input[i]==0&&count==0)
	continue;
      else
	count++;
    }
    for (int i=0;i<cc;i++){
      cout<<ans[i];
    }
    cout<<endl;
  }
}

C++: #include <iostream>
#include <vector>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <algorithm>

using namespace std;
using vi = vector<int>;
using vvi = vector<vi>;
template<class T> using hset = unordered_set<T>;
template<class Key, class T> using hmap = unordered_map<Key, T>;

int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
vector<vector<char> > phone = {
    {},
    {' ', '.', ',', '!', '?'},
    {'c', 'a', 'b'},
    {'f', 'd', 'e'},
    {'i', 'g', 'h'},
    {'l', 'j', 'k'},
    {'o', 'm', 'n'},
    {'s', 'p', 'q', 'r'},
    {'v', 't', 'u'},
    {'z', 'w', 'x', 'y'}
};

int main() {
    int n; cin >> n;
    string s;
    for (int i = 0; i < n; i++) {
        cin >> s;
        int k = 0, kl = 0;
        for (char c : s) {
            if (c - '0' == 0) {
                if (kl == 0) continue;
                cout << phone[kl][k];
                k = 0;
                kl = 0;
            } else {
                kl = c - '0';
                k = (k+1) % phone[kl].size();
            }
        }
        cout << endl;
    }
    return 0;
}

C++: #include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<numeric>

using namespace std;

#define all(i) i.begin(), i.end()
#define rep(i,n) for(int i=0;i<n;i++)

int main()
{
	int num = 0; cin >> num;
	string dat[12] = { "", ".,!? ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
	rep(i, num)
	{
		string str; cin >> str;
		vector<int> hit(10, 0);
		rep(j, (int)str.size())
		{
			hit[str[j] - '0'] += 1;
			if (j == 0 || str[j - 1] == '0') {}
			else if (str[j] == '0')
			{
				int n = 0, tmp = str[j - 1] - '0';
				n = hit[tmp] % (int)dat[tmp].size();
				if (n == 0){ n = hit[tmp] + 1; }
				if (n >= 3 && (int)dat[tmp].size() == 3) { n -= 1; }
				printf("%c", dat[tmp][n - 1]);
				rep(i, 10){ hit[i] = 0; }
			}
		}
		printf("\n");
	}
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>	// require sort next_permutation count __gcd reverse etc.
#include <cstdlib>	// require abs exit atof atoi 
#include <cstdio>		// require scanf printf
#include <functional>
#include <numeric>	// require accumulate
#include <cmath>		// require fabs
#include <climits>
#include <limits>
#include <cfloat>
#include <iomanip>	// require setw
#include <sstream>	// require stringstream 
#include <cstring>	// require memset
#include <cctype>		// require tolower, toupper
#include <fstream>	// require freopen
#include <ctime>		// require srand
#define rep(i,n) for(int i=0;i<(n);i++)
#define ALL(A) A.begin(), A.end()

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
const string button[10] = { 
	"", ".,!? ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"
};

int main()
{
	ios_base::sync_with_stdio(0);
	int n; cin >> n;
	while (n-- ){
		string s = ""; cin >> s;
		int m =  s.length();
		map<int,int> p; p.clear();
		string res = "";

		rep (i, m ){
			if (s[i] != '0' ){
				p[(int)(s[i]-'0')]++;
			}else{
				map<int,int>::iterator it = p.begin();
				if (it == p.end() ) continue;
				int a = (*it).first;
				int b = (*it).second; b--;
				int len = button[a].length();
				res += button[a][b%len];
				p.clear();
			} // end if
		} // end rep
		cout << res << endl;

	} // end while

	return 0;
}