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++: #include<cstdio>
using namespace std;

int n;
char s[1030];
char list[9] = {'a', 'd', 'g', 'j', 'm', 'p', 't', 'w'};
char one[5] = {'.', ',', '!', '?', ' '};

int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%s", s);
    char count = -1;
    bool flag = false;
    for (int j = 0; s[j] != 0; j++) {
      if (s[j] == '0') {
        if (!flag) continue;
        if (s[j-1] == '1') printf("%c", one[count % 5]);
        else if (s[j-1] == '7' || s[j-1] == '9') printf("%c", list[s[j-1] - '2'] + count % 4);
        else printf("%c", list[s[j-1] - '2'] + count % 3);
        flag = false;
        count = -1;
      } else {
        flag = true;
        count++;
        if (count == 60) count = 0;
      }
    }
    printf("\n");
  }
}

C++: 
//http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2006

#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<cmath>
#include<climits>
#include<ctime>
#include<cstring>
#include<numeric>

#define ALL(v) (v).begin(),(v).end()
#define REP(i,p,n) for(int i=p;i<(int)(n);++i)
#define rep(i,n) REP(i,0,n)
#define dump(a) (cerr << #a << "=" << (a) << endl)
#define DUMP(list) cout << "{ "; for(auto nth : list){ cout << nth << " "; } cout << "}" << endl;

using namespace std;

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

int main() 
{
	int N;
	cin >> N;
	rep(nth,N)
	{
		int count=0;
		string msg;
		cin >> msg;
		rep(i,msg.length())
		{
			if(msg[i] == msg[i+1]){
			count++;
			}else{
				string tmp = table[(msg[i]-'0')];
				char word = tmp[ count % (tmp.length()) ];
				if(word != '#'){ cout << word; }
				count=0;
			}
		}
		cout << endl;
	}
	return 0;
}

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

int main(){
  int n;
  int len;
  int count;
  int i,j;
  int num;
  int flg;
  char moji[10][6]={
    {' ',' ',' ',' ',' '},
    {'.',',','!','?',' '},
    {'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'}
  };

  cin >> n;

  for(i = 0 ; i < n ; i++){
    num = 0;
    count = -1;
    string str;

    cin >> str;

    for(j = 0 ; j < str.size() ; j++){
      flg = 1;
      if(str[j]=='1'){
	num = 1; 
      }else if(str[j]=='2'){
	num = 2; 
      }else if(str[j]=='3'){
	num = 3; 
      }else if(str[j]=='4'){
	num = 4;
      } else if(str[j]=='5'){
	num = 5; 
      }else if(str[j]=='6'){
	num = 6; 
      } else if(str[j]=='7'){
	num = 7;
      }else if(str[j]=='8'){
	num = 8; 
      }else if(str[j]=='9'){
	num = 9; 
      }else{
	if(num == 0){
	  continue;
	}

	if(num == 1){
	  count = count % 5;
	}else if(num == 7 || num == 9){
	  count = count % 4;
	}else{
	  count = count % 3;
	}

	cout << moji[num][count];

	flg = 0;
	count = -1;
	num = 0;
      }
      if(flg == 1) count++;
    }
    cout << endl;
  }
  return 0;
}