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 <algorithm>
#include <iostream>
#include <limits.h>
#include <stdlib.h>
#include <string>
#include <vector>

#define el endl
#define fd fixed
#define INF INT_MAX/2-1

using namespace std;

int main() {
  int n, pre, cur, count;
  string s;
  string org[] = {".,!? ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
  vector<string> button(org, org+9);
  cin >> n;
  while (n--) {
    cin >> s;
    pre = 0;
    for (int i = 0; i < s.length(); i++) {
      cur = (int)(s[i]-'0');
      if (pre == 0) {
        if (cur != 0) {
          pre = cur;
        }
      } else {
        if (cur == 0) {
          cout << button[pre-1][count];
          pre = 0;
          count = 0;
        } else {
          count = (count+1)%button[pre-1].length();
        }
      }
    }
    cout << el;
  }
}

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