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

using namespace std;

int main(void){
	//FILE* fp_in = freopen("data.txt", "r", stdin);

	int n;
	cin >> n;

	char c[10][5] = {
		{'*', '*', '*', '*', '*'},
		{'.', ',', '!', '?', ' '},
		{'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', '*'}
	};
	int max[] = {
	//  0, 1, 2, 3, 4, 5, 6, 7, 8, 9
		0, 5, 3, 3, 3, 3, 3, 4, 3, 4
	};

	for(int i = 0; i < n; i++) {
		string number;
		string message;
		int num, flg = 0, sel = 0;
		char ch;
		cin >> number;

		for(int j = 0; j < number.length(); j++) {
			num = atoi( number.substr(j, 1).c_str() );
			if(num == 0) {
				if(flg == 0) continue;
				else message += ch;
				flg = 0;
				sel = 0;
			} else {
				flg = 1;
				ch = c[num][sel];
				sel ++;
				if(sel >= max[num]) sel = 0;
			}
		}

		cout << message << endl;

	}

	//while(1){}
	return 0;
}

C++: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<n;i++)
using namespace std;

string keitai[]{".,!? ","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
int main(){
	string s;
	while(cin>>s){
		int cnt=0;
		string ans;
		rep(i,s.size()){
			if(s[i]=='0'){
				if(cnt)ans+=keitai[s[i-1]-'1'][(cnt-1)%keitai[s[i-1]-'1'].size()];
				cnt=0;
			}
			if(i&&s[i-1]!=s[i])cnt=0;
			else cnt++;
		}
		cout<<ans<<endl;
	}
}

C++: #include <bits/stdc++.h>
#define REP(i,n) for (int i=0;i<(n);i++)
#define ALL(a) (a).begin(),(a).end()
#define RFOR(i,a,b) for (int i=(b)-1;i>=(a);i--)
#define REP(i,n) for (int i=0;i<(n);i++)
#define RREP(i,n) for (int i=(n)-1;i>=0;i--)
#define ll long long
#define ull unsigned long long
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

using namespace std;

int main(){
  int n,j,knum;
  string s;
  string c[10] = {"",".,!? ","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
  cin >> n;
  while(n){
    cin >> s;
    for(int i = 0;i<s.size();i++){
      if(s[i] == '0')continue;
      for(j=0;j<s.size();j++)
	if(s[i+j+1] == '0')break;
      knum = j%c[s[i]-'0'].size();
      cout << c[s[i]-'0'][knum];
      i += j;
    }
    cout << "\n";
    n--;
  }

  return 0;
}

C++: #include <algorithm>
#include <cassert>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    int n;
    cin >> n;

    auto split = [](const string& s, char delimiter) {
        stringstream ss;
        ss << s;
        string t;
        vector<string> r;
        while (getline(ss, t, delimiter)) {
            if (!t.empty()) {
                r.push_back(t);
            }
        }
        return r;
    };

    auto encode = [](const string& s) {
        const auto c = s[0];
        const auto len = s.size() - 1;
        if (c == '1') {
            switch (len % 5) {
            case 0:
                return '.';
            case 1:
                return ',';
            case 2:
                return '!';
            case 3:
                return '?';
            case 4:
                return ' ';
            }
        }
        else if (c == '2') {
            switch (len % 3) {
            case 0:
                return 'a';
            case 1:
                return 'b';
            case 2:
                return 'c';
            }
        }
        else if (c == '3') {
            switch (len % 3) {
            case 0:
                return 'd';
            case 1:
                return 'e';
            case 2:
                return 'f';
            }
        }
        else if (c == '4') {
            switch (len % 3) {
            case 0:
                return 'g';
            case 1:
                return 'h';
            case 2:
                return 'i';
            }
        }
        else if (c == '5') {
            switch (len % 3) {
            case 0:
                return 'j';
            case 1:
                return 'k';
            case 2:
                return 'l';
            }
        }
        else if (c == '6') {
            switch (len % 3) {
            case 0:
                return 'm';
            case 1:
                return 'n';
            case 2:
                return 'o';
            }
        }
        else if (c == '7') {
            switch (len % 4) {
            case 0:
                return 'p';
            case 1:
                return 'q';
            case 2:
                return 'r';
            case 3:
                return 's';
            }
        }
        else if (c == '8') {
            switch (len % 3) {
            case 0:
                return 't';
            case 1:
                return 'u';
            case 2:
                return 'v';
            }
        }
        else if (c == '9') {
            switch (len % 4) {
            case 0:
                return 'w';
            case 1:
                return 'x';
            case 2:
                return 'y';
            case 3:
                return 'z';
            }
        }
        assert(false);
    };

    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;

        auto r = split(s, '0');
        string rr;
        transform(begin(r), end(r), back_inserter(rr), encode);

        cout << rr << endl;
    }
}