Go: /*
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2006&lang=jp
Keitai Message
*/

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

// 標準入力を取得するScannerのインスタンスを作成
var scanner = bufio.NewScanner(os.Stdin)

// 標準入力で各行を読み込みstringとして返す
func readLine() string {
	if scanner.Scan() {
		return scanner.Text()
	}
	return ""
}

func main() {
	// 1: . , ! ? (スペース)
	// 2: a b c
	// 3: d e f
	// 4: g h i
	// 5: j k l
	// 6: m n o
	// 7: p q r s
	// 8: t u v
	// 9: w x y z
	// 0: 確定ボタン

	// 改行から空白区切りに変更
	scanner.Split(bufio.ScanWords)
	line, _ := strconv.Atoi(readLine()) // 5行標準入力が続く

	table := []string{
		"",      // 0 index調整ためダミーデータ
		".,!? ", // 1
		"abc",   // 2
		"def",   // 3
		"ghi",   // 4
		"jkl",   // 5
		"mno",   // 6
		"pqrs",  // 7
		"tuv",   // 8
		"wxyz"}  // 9

	// 5行分の標準入力を格納するsliceを作成する
	messages := make([]string, 0, line)

	// sliceに標準入力の内容を格納する
	for i := 0; i < line; i++ {
		messages = append(messages, readLine()) // messages=[20 220 222220 44033055505550666011011111090666077705550301110 000555555550000330000444000080000200004440000]
	}

	// 各行毎に解析する
	for _, message := range messages { // message=000555555550000330000444000080000200004440000
		// 0で分割する
		messageSlice := strings.Split(message, "0") // messageSlice=[   55555555    33    444    8    2    444    ]
		for _, word := range messageSlice {
			if word == "" {
				// NOP.
				// 0をセパレーターにしているので空文字がsliceに格納されてい箇所がある
				// 何もしない
			} else { // word=55555555
				// 一文字取り出しコード値をASCII文字に変換する
				ascii := string((word[0])) // word[0]=5

				// ASCII文字からintへ変換する(tableのindexになる)
				number, _ := strconv.Atoi(ascii)

				// 入力回数をカウントする
				count := len(word) // 5

				// 同じ数字を続けて入力すると変化する文字はループすることを考慮する
				for count > len(table[number]) { // 5 > 3
					count -= len(table[number]) // 2
				}

				// キー配列
				keys := table[number]                   //jkl
				fmt.Printf("%s", string(keys[count-1])) //k
			}
		}
		fmt.Println() // 改行
	}
}

C++: #define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include "bits/stdc++.h"
#define REP(i,a,b) for(int i=a;i<b;++i)
#define rep(i,n) REP(i,0,n)
#define ll long long
#define ull unsigned ll
typedef long double ld;
#define ALL(a) (a).begin(),(a).end()
#define ifnot(a) if(not a)
#define dump(x)  cerr << #x << " = " << (x) << endl
using namespace std;

void reader(int &a) { scanf("%d", &a); }
void reader(double &a) { scanf("%lf", &a); }
void reader(char a[]) { scanf("%s", a); }
void reader(char &a) { scanf(" %c", &a); }
void reader(ll &a) { scanf("%lld", &a); }
void reader(ull &a) { scanf("%llu", &a); }
// void reader(string& a){cin >> a;};
template<class T, class U> void reader(T& t, U& u) { reader(t); reader(u); }
template<class T, class U, class V> void reader(T& t, U& u, V& v) { reader(t); reader(u); reader(v); }

void writer(const int a, char c) { printf("%d", a); putchar(c); }
void writer(const ll a, char c) { printf("%lld", a); putchar(c); }
void writer(const ull a, char c) { printf("%llu", a); putchar(c); }
void writer(const double a, char c) { printf("%.20lf", a); putchar(c); }
void writer(const char a[]) { printf("%s", a); };
void writer(const char a[], char c) { printf("%s", a); putchar(c); };
void writer(const char a, char c) { putchar(a); putchar(c); };
template<class T> void writerLn(T t) { writer(t, '\n'); }
template<class T, class U> void writerLn(T t, U u) { writer(t, ' '); writer(u, '\n'); }
template<class T, class U, class V> void writerLn(T t, U u, V v) { writer(t, ' '); writer(u, ' '); writer(v, '\n'); }
template<class T> void writerArr(T x[], int n) { int i; if (!n) { putchar('\n'); return; }rep(i, n - 1) writer(x[i], ' '); writer(x[n - 1], '\n'); }
template<class T> void writerVec(vector<T> x) { int n = x.size(); int i; if (!n) { putchar('\n'); return; }rep(i, n - 1) writer(x[i], ' '); writer(x[n - 1], '\n'); }

vector<string> split(const string &str, char sep) { vector<string> v; stringstream ss(str); string buffer; while (getline(ss, buffer, sep)) { v.push_back(buffer); }return v; }
// #define int ll
bool test = 1;
int dx[] = { 0,1,0,-1 };
int dy[] = { 1,0,-1,0 };
#define MAX 300000
//.....................
ull mod = (int)1e9 + 7;

signed main(void)
{
	string s[10];
	s[1] = ".,!?";
	s[2] = "abc";
	s[3] = "def";
	s[4] = "ghi";
	s[5] = "jkl";
	s[6] = "mno";
	s[7] = "pqrs";
	s[8] = "tuv";
	s[9] = "wxyz";
	int t;
	cin >> t;
	rep(i, t) {
		string res;
		string message;
		cin >> message;
		char now;
		rep(i, message.size()) {
			now = message[i];
			if (now == '0') continue;
			int cnt = 0;
			REP(j, i + 1, message.size()) {
				if (message[j] != now) {
					cnt = j - i;
					break;
				}
			}
			i += cnt;
			res += s[now - '0'][(cnt - 1) % s[now - '0'].size()];
		}
		cout << res << endl;
	}
	return 0;
}

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

string in;
int j = 0;
int index = -1;

string c_1 = ".,!? " ;
string c_2 = { 'a','b','c'};
string c_3 = { 'd','e','f'};
string c_4 = { 'g','h','i'};
string c_5 = { 'j','k','l'};
string c_6 = { 'm','n','o'};
string c_7 = { 'p','q','r','s'};
string c_8 = { 't','u','v'};
string c_9 = { 'w','x','y','z'};

char func(string s)
{
	while (in[j] != '0')
	{
		index++;
		if (index >= s.size())index = 0;
		j++;
	}
	return s[index];
}

int main()
{
	int n;
	cin >> n;
	cin.ignore();
	REP(i, n)
	{
		in.clear();
		getline(cin, in);
		j = 0;
		while (in[j] != '\0')
		{
			index = -1;
			switch (in[j])
			{
			case '1':
				cout << func(c_1);
				break;
			case '2':
				cout << func(c_2);
				break;
			case '3':
				cout << func(c_3);
				break;
			case '4':
				cout << func(c_4);
				break;
			case '5':
				cout << func(c_5);
				break;
			case '6':
				cout << func(c_6);
				break;
			case '7':
				cout << func(c_7);
				break;
			case '8':
				cout << func(c_8);
				break;
			case '9':
				cout << func(c_9);
				break;
		    }
			j++;
		}
		cout << endl;
	}
	return 0;
}

C++: #include<bits/stdc++.h>

using namespace std;

int main(){
	string input;
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>input;
		char first=input[0];
		int count=1;
		for(int j=1;j<input.size();j++){
			if(first==input[j])count++;
			if(input[j]=='0'){
				switch(first){
					case '1':
						switch(count%5){
							case 1:cout<<".";break;
							case 2:cout<<",";break;
							case 3:cout<<"!";break;
							case 4:cout<<"?";break;
							case 0:cout<<" ";break;
						}break;
					case '2':
						switch(count%3){
							case 1:cout<<"a";break;
							case 2:cout<<"b";break;
							case 0:cout<<"c";break;
						}break;
					case '3':
						switch(count%3){
							case 1:cout<<"d";break;
							case 2:cout<<"e";break;
							case 0:cout<<"f";break;
						}break;
					case '4':
						switch(count%3){
							case 1:cout<<"g";break;
							case 2:cout<<"h";break;
							case 0:cout<<"i";break;
						}break;
					case '5':
						switch(count%3){
							case 1:cout<<"j";break;
							case 2:cout<<"k";break;
							case 0:cout<<"l";break;
						}break;
					case '6':
						switch(count%3){
							case 1:cout<<"m";break;
							case 2:cout<<"n";break;
							case 0:cout<<"o";break;
						}break;
					case '7':
						switch(count%4){
							case 1:cout<<"p";break;
							case 2:cout<<"q";break;
							case 3:cout<<"r";break;
							case 0:cout<<"s";break;
						}break;
					case '8':
						switch(count%3){
							case 1:cout<<"t";break;
							case 2:cout<<"u";break;
							case 0:cout<<"v";break;
						}break;
					case '9':
						switch(count%4){
							case 1:cout<<"w";break;
							case 2:cout<<"x";break;
							case 3:cout<<"y";break;
							case 0:cout<<"z";break;
						}break;
				}
				first=input[j+1];
				count=0;
			}	
		}
		
			cout<<endl;	
	}
}