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>
using namespace std;
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		string s;
		cin>>s;
		int ans=0;
		int j=0;
		while(j<s.size()){
			int cnt=0;
			int t=0;
			while(s[j+t+1]!='0'){
				if(s[j]=='0')break;
				t++;
			}
			if(s[j]=='1'){
				if((t+1)%5==1){
					cout<<".";
				}
				if((t+1)%5==2){
					cout<<",";
				}
				if((t+1)%5==3){
					cout<<"!";
				}
				if((t+1)%5==4){
					cout<<"?";
				}
				if((t+1)%5==0){
					cout<<" ";
				}
			}
			if(s[j]=='2'){
				if((t+1)%3==1){
					cout<<"a";
				}
				if((t+1)%3==2){
					cout<<"b";
				}
				if((t+1)%3==0){
					cout<<"c";
				}
			}
			if(s[j]=='3'){
				if((t+1)%3==1){
					cout<<"d";
				}
				if((t+1)%3==2){
					cout<<"e";
				}
				if((t+1)%3==0){
					cout<<"f";
				}

			}
			if(s[j]=='4'){
				if((t+1)%3==1){
					cout<<"g";
				}
				if((t+1)%3==2){
					cout<<"h";
				}
				if((t+1)%3==0){
					cout<<"i";
				}
			}
			if(s[j]=='5'){
				if((t+1)%3==1){
					cout<<"j";
				}
				if((t+1)%3==2){
					cout<<"k";
				}
				if((t+1)%3==0){
					cout<<"l";
				}
			}
			if(s[j]=='6'){
				if((t+1)%3==1){
					cout<<"m";
				}
				if((t+1)%3==2){
					cout<<"n";
				}
				if((t+1)%3==0){
					cout<<"o";
				}
			}
			if(s[j]=='7'){
				if((t+1)%4==1){
					cout<<"p";
				}
				if((t+1)%4==2){
					cout<<"q";
				}
				if((t+1)%4==3){
					cout<<"r";
				}
				if((t+1)%4==0){
					cout<<"s";
				}
			}
			if(s[j]=='8'){
				if((t+1)%3==1){
					cout<<"t";
				}
				if((t+1)%3==2){
					cout<<"u";
				}
				if((t+1)%3==0){
					cout<<"v";
				}
			}
			if(s[j]=='9'){
				if((t+1)%4==1){
					cout<<"w";
				}
				if((t+1)%4==2){
					cout<<"x";
				}
				if((t+1)%4==3){
					cout<<"y";
				}
				if((t+1)%4==0){
					cout<<"z";
				}
			}
			j+=t+1;
			
		}
		cout<<endl;
	}
	return 0;
}

C++: #include <iostream>
#include <string>
using namespace std;
int main(){
	int n;
	cin<<n;
	for(int i=0;i<N;i++){
		
		string key[]={".,!?, ","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
	}
	return 0;
}

C++: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define mod 1000000007 //1e9+7
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 21

struct Data{
  int len;
  char c[5];
};

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


void calc(){
  string s,ans;
  vector<int> vec;
  
  cin >> s;

  for(int i=1;i<s.size();i++){
    if(s[i-1]!='0' && s[i]=='0') vec.push_back(i);
  }

  
  int last = -1;
  for(int i=0;i<vec.size();i++){
    ans += data[s[vec[i]-1]-'0'][(vec[i]-(last+2))%(int)(data[s[vec[i]-1]-'0'].size())];
    last = vec[i];
  }
    
  cout << ans << endl;
  
  return;
}

int main(){
  int n;

  scanf("%d",&n);
  
  for(int i=0;i<n;i++){
    calc();
  }

  return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <climits>
#include <algorithm>
#include <string>
#include <sstream>
#include <complex>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <fstream>

using namespace std;
#define SZ(x) (int)(x).size()
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REPR(i,n) for(int i=(n)-1;i>=0;i--)
#define ALL(s) (s).begin(), (s).end()
#define so(V) sort(ALL(V))
#define rev(V) reverse(ALL(V))
#define uni(v) v.erase( unique(ALL(v)) , v.end());

typedef long long unsigned int llu;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vll;
typedef vector<bool> vb;
const double EPS = 1e-9;
const int MOD = 1e9 + 7;
const int INF = (1 << 29);
const ll LINF = 1e18;
const double PI = acos(-1);

template<typename T>vector<T> make_v(size_t a) { return vector<T>(a); }
template<typename T, typename... Ts>auto make_v(size_t a, Ts... ts) { return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...)); }
template<typename T, typename U, typename... V>
typename enable_if<is_same<T, U>::value != 0>::type
fill_v(U & u, const V... v) { u = U(v...); }
template<typename T, typename U, typename... V>
typename enable_if<is_same<T, U>::value == 0>::type
fill_v(U & u, const V... v) { for (auto& e : u) fill_v<T>(e, v...); }
template<class T> bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> bool chmin(T& a, const T& b) { if (a > b) { a = b; return 1; } return 0; }

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	vector<vector<char> > C;
	C.push_back({ '.',',','!','?',' ' });
	C.push_back({ 'a','b','c' });
	C.push_back({ 'd','e','f' });
	C.push_back({ 'g','h','i' });
	C.push_back({ 'j','k','l' });
	C.push_back({ 'm','n','o' });
	C.push_back({ 'p','q','r','s' });
	C.push_back({ 't','u','v' });
	C.push_back({ 'w','x','y','z' });
	int N;
	cin >> N;
	REP(i, N) {
		string S;
		cin >> S;
		int ind = 0;
		string ans = "";
		while (ind < SZ(S)) {
			char c = S[ind];
			ind++;
			if (c == '0') {
				continue;
			}
			int cnt = 0;
			while (S[ind] != '0') {
				ind++;
				cnt++;
			}
			ans += C[c - '1'][cnt % SZ(C[c-'1'])];
		}
		cout << ans << endl;
	}
	return 0;
}

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

char hyo[9][5];

char moji(int char_, int count);

int main(void)
{
	int i1,i2;
	char c = 'a';
	char cc;
	string s;
	int n;
	int m;
	int count;

		/* syokika */
		for(i1=0;i1<9;i1++){	
			for(i2=0;i2<5;i2++){
				hyo[i1][i2] = '1';
			}
		}


		/* hyo sakusei */
		hyo[0][0] = '.';
		hyo[0][1] = ',';
		hyo[0][2] = '!';
		hyo[0][3] = '?';
		hyo[0][4] = ' ';


		for( i1=1; i1<9; i1++){
			for(i2=0; i2<4; i2++){
				
				if(i2 == 3) {

					if( i1 == 6 || i1 == 8) {}
					else continue;
				}

				hyo[i1][i2] = c;
				c++;
			}
		}



		cin >> n;

		for(i2=0;i2<n;i2++){


			cin >> s;

			count = 0;
			m = 0;
			for(i1=0;i1<s.size();i1++){
			

				if( s[i1]=='0'){
					if(m != 0){
						cc = moji(m,count);
						count = 0;
						m = 0;
					    cout << cc;
					}
				}
				else{

					c = s[i1];
					m = c - 48;
					count++;
				}
			}

			cout << endl;


		}

	return 0;

}


char moji(int char_, int count)
{

	int n;
	count--;
	if( char_ == 1){
		n = count%5;
	}
	else if( char_ == 7 || char_ == 9){
		n = count%4;
	}
	else {
		n = count%3;
	}

	return hyo[char_-1][n];
}