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;

struct wait{
	char num;
	int count;
};

void out(int, int);

int main(){
	int n;
	string input;
	struct wait now;
	int i, j;
	
	cin >> n;
	for(i = 0; i < n; i++){
		now.count = 0;
		cin >> input;
		
		for(j = 0;j < input.size(); j++){
			if(input[j] == '0'){
				out(now.num - '0', now.count);
				now.count = 0;
			}
				
			else{
				now.num = input[j];
				now.count++;
			}
		}
		cout << endl;
	}
	
	return 0;
}

void out(int num, int count){
	char output[9][5] = {{'.', ',', '!', '?', ' '}, {'a', 'b', 'c'}, {'d', 'e', 'f'},
						{'g', 'h', 'i'}, {'j', 'k', 'l'}, {'m', 'n', 'o'},
						{'p', 'q', 'r', 's'}, {'t', 'u', 's'}, {'w', 'x', 'y', 'z'}};
	int size[] = {5, 3, 3, 3, 3, 3, 4, 3, 4};
	int which;
	
	if(count == 0)
		return;
	
	if(count % size[num - 1] == 0)
		which = size[num - 1] - 1;
	else
		which = count % size[num - 1] - 1;
	cout << output[num - 1][which];
}

C++: #include<iostream>
#include<string>

using namespace std;

int main(){

	string data[] = { ".,!? ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
	char inp;
	int n, cnt, num;
	string ans;

	cin >> n;

	getchar();

	for (int i = 0; i < n; i++){

		cnt = 0;
		ans = ("");

		while (1){

			inp = getchar();

			if (inp == '\n') break;
			if (inp != '0'){
				num = inp - '0';
				cnt++;
			}
			else{
				if (cnt > 0){
					ans += data[num-1][(cnt-1)%data[num-1].size()];
					cnt = 0;
				}
			}
		}

		cout << ans << endl;
	}

	return 0;
}

C++: #include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<stack>
#include<bitset>
#include<map>
using namespace std;

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


string s;
bool input(){
  s="";
  if(!(cin>>s)){
    return false;
  }

  return true;
}


string solve(){
  string res = "";
  int n=-1;
  for(int i=0;i<s.size();i++){
    if(s[i]=='0'){
      if(n==-1)continue;
      int tmp = s[i-1]-'0';
      res += list[tmp-1][n%list[tmp].size()];
      n=-1;
    }else{
      n++;
    }
  }
  return res;
}

int main(){
  int c=0;
  cin>>c;
  for(int i=0;i<c;i++){
    input();
    string ans = solve();
    if(ans.size()!=0)cout<<ans<<endl;
  }
}

C++: #include <bits/stdc++.h>
using namespace std;

#define int long long

signed main() {
	int n;
	cin >> n;
	string dat[10] = {".,!? ",
										"abc",
										"def",
										"ghi",
										"jkl",
										"mno",
										"pqrs",
										"tuv",
										"wxyz"};										
	while ( n-- ) {
		string s;
		cin >> s;
		int l = s.size();
		for ( int i = 0; i < l; i++ ) {
			char c = s[i];
			int cnt = 0;
			for ( i = i+1; i < l; i++ ) {
				if ( s[i] != c ) break;
				cnt++;
			}
			i--;
			if ( c == '0' ) continue;
			int num = c-'0'-1;
			cnt %= dat[num].size();
			cout << dat[num][cnt];
		}
		cout << endl;
	}
	return 0;
}

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

string keitai(string s){
	string t="";
	char k1[6]=".,!? ";
		
	for(int i=0; i<s.size(); ++i){
		
		if(s[i]=='0') continue;
		else if(s[i]=='1'){
			int c1=0;
			do{
				++i;	
				++c1;
			}while(s[i]=='1');
			
			if(s[i]=='0') t += k1[(c1-1)%5];				
		}
		else{
			char c=s[i];
			int c2=0;
			do{
				++i;	
				++c2;
			}while(s[i]==c);
			if(s[i]=='0'){
				if('2'<=c && c<='6') t+='a'+((c-'2')*3)+((c2-1)%3);
				else if(c=='7') t+='p'+(c2-1)%4;
				else if(c=='8') t+='t'+(c2-1)%3;
				else if(c=='9') t+='w'+(c2-1)%4;
			}			
		}
	
	}
	
	return t;
}

int main(){
	int n;
	scanf(" %d", &n);
	for(int i=0; i<n; ++i){
		string s;
		cin >> s;	
		cout << keitai(s) << 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'};
char mozi(int,char);
int main(){
	int n;
	cin>>n;

	for(int i=0;i<n;i++){
		string keitai;

		cin>>keitai;
		int cnt=0;
		for(int i=0;i<keitai.size();i++){

			if(keitai[i]=='0')	continue;

			else{
				int kazu=1;
				while(keitai[i+1]!='0'){
					kazu++;
					i++;
				}
			cout<<mozi(kazu,keitai[i]);
			i++;
			cnt++;
			}
		}
		cout<<endl;
	}
	return 0;
}


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';
	}
}

C++: #include<bits/stdc++.h>
using namespace std;
int main(){
	char a[9][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 n,b=0,c=0,d=0;
	string s;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>s;b=d=c=0;
			for(int j=0;j<s.size();j++){
				if(s[j]=='0'&&c>0){
					if(s[j-1]=='1')d=(c-1)%5;
					else if(s[j-1]=='6'||s[j-1]=='8')d=(c-1)%4;
					else d=(c-1)%3;
					cout<<a[(int)(s[j-1]-'0')-1][d];
				c=0;
				}
				else c++;
				}
				cout<<endl;
	}
	return 0;
}