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<bits/stdc++.h>
using namespace std;
typedef long long ll;

//ofstream outputfile("test.txt");
int main(){
    //outputfile.close();
    int n;
    string t[10];
    t[1] = ".,!? ";
    t[2] = "abc";
    t[3] = "def";
    t[4] = "ghi";
    t[5] = "jkl";
    t[6] = "mno";
    t[7] = "pqrs";
    t[8] = "tuv";
    t[9] = "wxyz";
    int cc=0;
    while(cin>>n){
        cc++;
        string s[n];
        string ans="";
        int cnt=0;
        for(int i=0;i<n;i++)cin>>s[i];
        for(int i=0;i<n;i++){
            ans="";
            //if(s[i][i]=='0')break;
            for(int j=0;j<s[i].length()-1;j++){
                cnt=0;
                bool fl = false;
                while(1){
                    if(s[i][j]=='0'){
                        j++;
                        if(j>(s[i].length()-1)){
                            fl=true;
                            break;
                        }
                        continue;
                    }
                    if(s[i][j]==s[i][j+1]){
                        cnt++;j++;
                    }
                    if(s[i][j+1]=='0'){
                        break;
                    }
                }
                if(fl)break;
                int tmp = s[i][j]-'0';
                ans += t[tmp][(cnt)%t[tmp].length()];
                j++;
            }
        cout<<ans<<endl;
        }
        if(cc==n)break;
    }
}

C++: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>

#define FOR(i,k,n) for (int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)

using namespace std;

const int INF = 1000000000;
const double eps = 1e-8;

int main(void) {
  string tb[] = {"",".,!?","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
  int sz[]={0,4,3,3,3,3,3,4,3,4};
  int n;cin>>n;
  REP(i,n){
    string s;
    cin>>s;
    int cnt = 0;
    int ochar = 0;
    REP(j,s.size()){
      if(s[j]=='0'){
        if(ochar!=0)
          cout<<tb[ochar][cnt%sz[ochar]];
        ochar = 0;
        cnt=0;
      }else{
        if(ochar==(s[j]-'0'))
          cnt++;
        else{
          cnt=0;
          ochar=s[j]-'0';
        }
      }
    }
    cout<<endl;
  }
  return 0;
}