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 <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <numeric>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#include <sstream>
#include <complex>

using namespace std;

#define FOR(i,a,b) for(long long i=(a);i<(b);i++)
#define REP(i,N) for(long long i=0;i<(N);i++)
#define ALL(s) (s).begin(),(s).end()
#define fi first
#define se second

#define PI acos(-1.0)
#define INF 1000000007
#define EPS 1e-10

typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<double, double> PD;
typedef pair<string, ll> PS;
typedef vector<ll> V;
typedef pair<P, char> PC;

int n;
string s;
string table[10] = { "", ".,!? ", "abc", "def",
"ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };

int main(){
	cin >> n;
	REP(i, n){
		cin >> s;
		string ans = "";
		REP(i, s.size()){
			int k = s[i] - '0';
			if (k != 0){
				int co = -1;
				while (s[i] != '0'){
					co++;
					i++;
					if (co > table[k].size() - 1)co = 0;
				}
				ans += table[k][co];
			}
		}
		cout << ans << endl;
	}
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>

// BEGIN CUT HERE
#ifdef _MSC_VER
#include <agents.h>
#endif
// END CUT HERE 

#define FOR(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) begin(v), end(v)
#define REV(v) rbegin(v), rend(v)
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define MP make_pair
#define MT make_tuple
#define X first
#define Y second

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

string str[] = {
	"",
	".,!? ",
	"abc",
	"def",
	"ghi",
	"jkl",
	"mno",
	"pqrs",
	"tuv",
	"wxyz",
};

int main(){
	ios::sync_with_stdio(false);

	int n;
	cin >> n;
	string s;
	while (n--){
		cin >> s;
		char ch = ' ';
		int cnt = 0;
		for (auto c : s){
			if (c == ch){
				++cnt;
			}else if(c == '0'){
				if (cnt) cout << str[ch-'0'][(cnt-1)%str[ch-'0'].size()];
				cnt = 0;
				ch = ' ';
			}
			else{
				ch = c;
				cnt = 1;
			}
		}
		if (cnt) cout << str[ch - '0'][(cnt - 1) % str[ch - '0'].size()];
		cout << endl;
	}


	return 0;
}

C++: #include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
	char inputString[80],outputString[80], hoge[2];
	char str;//êIÉê¶ªf[^ðÛ·éÏ
	int length,count,push,index,dataSet;
	int p[9][5] = { //e{^ðµ½Æ«ÌÏÚð ç©¶ßpÓ(óÌvfÍ@É·é)
		{'.' , ',' , '!' , '?' , ' '},
		{'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' , '@'},
	}; 
	scanf("%d", &dataSet);//ßÉf[^ZbgðüÍ

	for(int i=0 ; i<dataSet ; i++){//f[^ZbgÌ¾¯üÍ³¹é
		//ÏÌú»
		count = 0;
		index = 0;
		push  = 0;
		str   = 0;

		scanf("%s", inputString);//0-9Ì¶ÌÀÑüÍ

		length = strlen( inputString );//üÍ¶Ì·³ðßé
		
		for(int i=0 ; i<length ; i++){//ê¶¸Â¶Ì·³ª¾¯²×é

			//¶ðlÉÏ··é(Ï·µ½0-9ª»ÌÜÜµ½{^ÉÎ)
			hoge[0] = inputString[i];
			push = atoi(hoge);

			if(push==0){//mè{^:0¾Á½ç
				count = 0;
				if(str!=0){
					//êIÉÛ¶µÄ¢½¶ð¦ÉÇÁ
					outputString[index] = str;
					outputString[index+1] = '\0';
					str = 0;
					index++;
				}
			}
			else{//0ÈOÌ{^¾Á½ç

				//êIÉ»ÝÌ¶ðÛ¶
				str = p[push-1][count];
				//{^ðµ½ñðâ·
				count++;
				if(p[push-1][count]=='@' || count==5){
					count = 0;//{^ðµ½ñð0É·é
				}
			}
		}

		//¦Ì¶ñoÍ
		printf("%s \n", outputString );
	}

	return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
#define REP(i, a, n) for(int i=a; i<n; i++)

int main()
{
	int n;
	char str1[5] = { '.', ',', '!', '?', ' '};
	char strtop[8] = { 'a', 'd', 'g', 'j', 'm', 'p', 't', 'w' };
	cin >> n;

	REP(i, 0, n) {
		string str;
		cin >> str;
		int cnt = 0;
		char prev = '0';
		REP(j, 0, str.size()) {
			char sub = str[j];
			if (sub == prev && sub == '0') {
				continue;
			}
			else if (sub == prev) {
				cnt++;
			}
			else if (sub == '0') {
				if (prev == '1') cout << str1[cnt % 5];
				else if (prev == '7' || prev == '9') cout << (char)(strtop[(prev - '0')-2] + (cnt % 4));
				else cout << (char)(strtop[(prev - '0') - 2] + (cnt % 3));
				cnt = 0;
			}

			prev = sub;
		}
		cout << endl;
	}

	return 0;
}

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

char const mozi1[]={'.',',','!','?',' '},mozi2[]={'a','b','c'},mozi3[]={'d','e','f'},mozi4[]={'g','h','i'},mozi5[]={'j','k','l'},mozi6[]={'m','n','o'},mozi7[]={'p','q','r','s'},mozi8[]={'t','u','v'},mozi9[]={'w','x','y','z'};
void henkan(char *);
char mozi(int,char);
int main(){
	int n;
	cin>>n;

	for(int i=0;i<n;i++){
		char * keitai=new char[1024];
		cin>>keitai;
		henkan(keitai);
		delete[]keitai;
	}
	return 0;
}

void henkan(char * keitai){
	char *hyouzi=new char[72];
	fill(hyouzi,hyouzi+72,NULL);
	int length=strlen(keitai);
	int cnt=0;
	
	for(int i=0;i<length;i++){
		if(keitai[i]=='0')	continue;
		else{
			int kazu=1;
			while(keitai[i+1]!='0'){
				kazu++;
				i++;
			}
			hyouzi[cnt]=mozi(kazu,keitai[i]);
			i++;
			cnt++;
		}
	}
	
	cout<<hyouzi<<endl;
	delete[] hyouzi;
	return;
}
char mozi(int kazu,char keitai){
	switch (keitai)
	{
	case '1':
		kazu=kazu%5-1;
		if(kazu==-1)	return mozi1[4];
		return mozi1[kazu];
		
	case '2':
		kazu=kazu%3-1;
		if(kazu==-1)	return mozi2[2];
		return mozi2[kazu];
		
	case '3':
		kazu=kazu%3-1;
		if(kazu==-1)	return mozi3[2];
		return mozi3[kazu];
		
	case '4':
		kazu=kazu%3-1;
		if(kazu==-1)	return mozi4[2];
		return mozi4[kazu];
		
	case '5':
		kazu=kazu%3-1;
		if(kazu==-1)	return mozi5[2];
		return mozi5[kazu];
		
	case '6':
		kazu=kazu%3-1;
		if(kazu==-1)	return mozi6[2];
		return mozi6[kazu];
		
	case '7':
		kazu=kazu%4-1;
		if(kazu==-1)	return mozi7[3];
		return mozi7[kazu];
		
	case '8':
		kazu=kazu%3-1;
		if(kazu==-1)	return mozi8[2];
		return mozi8[kazu];
		
	case '9':
		kazu=kazu%4-1;
		if(kazu==-1)	return mozi9[3];
		return mozi9[kazu];
	default:
		return '0';
	}
}