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

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

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

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	n := nextInt(sc)

	for i := 0; i < n; i++ {
		message := nextString(sc)
		currentButton, count := 0, 0
		for _, word := range message {
			// 確定の処理を書く
			if word == '0' {
				if currentButton == 0 {
					count = 0
					continue
				}
				mod := len(table[currentButton])
				tmp := table[currentButton][(count-1)%mod]
				currentButton, count = 0, 0
				fmt.Printf("%c", tmp)
			} else {
				count++
				currentButton = int(word) - 48 // '0'はASCIIで48
			}
		}
		fmt.Println()
	}
}

func nextInt(sc *bufio.Scanner) int {
	sc.Scan()
	i, err := strconv.Atoi(sc.Text())
	if err != nil {
		panic(err)
	}
	return i
}

func nextString(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

C++: #define  _CRT_SECURE_NO_WARNINGS
#include "bits/stdc++.h"
#pragma comment (linker, "/STACK:526000000")

using namespace std;
typedef string::const_iterator State;
#define eps 1e-11L
#define MAX_MOD 1000000007LL
#define GYAKU 500000004LL

#define MOD 998244353LL
#define seg_size 262144*2LL
#define pb push_back
#define mp make_pair
typedef long long ll;
#define REP(a,b) for(long long (a) = 0;(a) < (b);++(a))
#define ALL(x) (x).begin(),(x).end()

unsigned long xor128() {
	static unsigned long x = 123456789, y = 362436069, z = 521288629, w = time(NULL);
	unsigned long t = (x ^ (x << 11));
	x = y; y = z; z = w;
	return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}

void init() {
	iostream::sync_with_stdio(false);
	cout << fixed << setprecision(10);
}

#define int ll
void solve() {
		string s;
		cin >> s;
		string sup[10] = { "1111",".,!? ","abc" , "def","ghi","jkl","mno","pqrs","tuv","wxyz" };
		int now = -1;
		int target = -1;
		REP(q, s.length()) {
			if (s[q] == '0') {
				if (target != -1) {
					cout << sup[target][now % sup[target].length()];
				}
				target = -1;
				now = -1;
			}
			else {
				now++;
				target = s[q] - '0';
			}
		}
		cout << endl;
}
#undef int

int main() {
	init();
	int test;
	cin >> test;
	REP(te,test)
	solve();
}

C++: #include <iostream>
#include <bitset>
#include <fstream>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
#include <numeric>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <functional>
#include <cctype>
#include <list>
#include <limits>
#include <unordered_map>
#define Debug 0
//#include <boost/multiprecision/cpp_int.hpp>

const double EPS = (1e-10);


using namespace std;
using Int = long long;
//using namespace boost::multiprecision;

const Int MOD = 1000000007;

Int mod_pow(Int x, Int n) {
    Int res = 1;
    while(n > 0) {
        if(n & 1) res = (res * x) % MOD; //ビット演算(最下位ビットが1のとき)
        x = (x * x) % MOD;
        n >>= 1; //右シフト(n = n >> 1)
    }
    return res;
}

//最大公約数
template<typename T>
T gcd(T a, T b) {
    return b != 0 ? gcd(b, a % b) : a;
}

//最小公倍数
template<typename T>
T lcm(T a, T b) {
    return a * b / gcd(a, b);
}

vector<string> button;

void solve(string &ret){
    string s; cin >> s;
    int num = 0;
    int cnt = 0;
    for (int i = 0; i < s.length(); i++) {
        if (s[i] == '0') {
            if (num) {
                ret.push_back(button[num][(cnt-1)%button[num].length()]);
            }
            num = 0;
            cnt = 0;
        } else {
            num = (int)(s[i] - '0');
            cnt++;
        }
    }
    return;
}

void init() {
    button = vector<string>(10);
    button[1] = ".,!? ";
    button[2] = "abc";
    button[3] = "def";
    button[4] = "ghi";
    button[5] = "jkl";
    button[6] = "mno";
    button[7] = "pqrs";
    button[8] = "tuv";
    button[9] = "wxyz";
}

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

    init();

    int N; cin >> N;
    vector<string> ans(N);
    for (int i = 0; i < N; i++) {
        string tmp;
        solve(tmp);
        ans[i] = tmp;
    }
    for (auto &i: ans) {
        cout << i << endl;
    }
}

C++: #include<algorithm>
#include<iostream>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
int main(){
  int i,j,k;
  int a[9]={5,3,3,3,3,3,4,3,4},n;
  int ln;
  char c[9][6]={".,!? ","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
  string s;
  string *t;
  cin>>n;
  t=new string[n];
  for(i=0;i<n;i++){
    cin>>s;
    ln=s.length();
    t[i]="";
    for(j=0;j<ln;j=k){
      for(;j<ln&&s[j]=='0';j++);
      for(k=j;k<ln&&s[j]==s[k];k++);
      if(k-j)
	t[i]+=c[s[j]-'1'][(k-j-1)%a[s[j]-'1']];
    }
  }
  for(i=0;i<n;i++)
    cout<<t[i]<<endl;
  delete[]t;
  return 0;
}

C++: #include <iostream>
#include <cstring>
using namespace std;
int main()
{
	int n, i, j, k, c, d, x;
	char s[1025], t[10][6] = {".,!? ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
	cin >> n;
	for (i = 0; i < n; i++)
	{
		cin >> s;
		for (j = x = d = 0; j < strlen(s); j++, d = c)
		{
			c = s[j] - '0';
			if (c == 0 && d != 0)
				cout << t[d-1][x%strlen(t[d-1])];
			else if (d == c)
				x++;
			else
				x = 0;
		}
		cout << endl;
	}
}

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

int main()
{
	int n, p, cnt;
	string key[] = {"", ".,!? ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
	string str;
	
	cin >> n;
	while (cin >> str) {
		for (char& c : str) {
			n = c - '0';
			if (n) {
				cnt++;
			} else {
				cout << key[p][(cnt-1) % key[n].size];
				cnt = 0;
			}
			p = n;
		}
		cout << endl;
	}
	
	return 0;
}

C++: #include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
using namespace std;

int N;
string wa[10]={ "",
		".,!? ",
		"abc",
		"def",
		"ghi",
		"jkl",
		"mno",
		"pqrs",
		"tuv",
		"wxyz"};
vector<char> ans;
int main(){
  cin >> N;
  for(int t=0;t<N;t++){
    string s;
    cin >> s;
    int pr = 0;
    int jd = 0;
    ans.clear();
    for(int i=0;i<(int)s.size();i++){
      int id = s[i]-'0';
      if( id == 0 ){
	//	cout << wa[pr][jd] << endl;
	if( pr!=0 ) ans.push_back(wa[pr][jd]);
      } else if( pr != id ){
	jd = 0;
      } else {
	jd = (jd+1)%(int)wa[id].size();
      }
      pr = id;
    }
    for(int i=0;i<(int)ans.size();i++){
      cout << ans[i];
    }
    cout << endl;
  }
}