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

//#define int long long
#define reps(i,s,n) for(int (i)=(s);(i)<(n);++(i))
#define rep(i,n) reps(i,0,n)
#define rept(i,n) rep(i,(n)+1)
#define repst(i,s,n) reps(i,s,(n)+1)
#define reprt(i,n,t) for(int (i)=(n);(i)>=(t);--(i))
#define repr(i,n) reprt(i,n,0)
#define each(itr,v) for(auto &(itr):(v))
#define all(c) (c).begin(),(c).end()
#define rall(c) (c).rbegin(),(c).rend()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define tmax(x,y,z) max(x,max(y,z))
#define tmin(x,y,z) min(x,min(y,z))
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
#define ln '\n'
#define bln(i,n) (((i)==(n)-1)?'\n':' ')
#define dbg(x) cout<<#x" = "<<(x)<<ln<<flush
#define dbga(x,n) {cout<<#x" : ";for(int (i)=0;i<(n);++i){cout<<((x)[i])<<(i==((n)-1)?'\n':' ')<<flush;}}
#define zero(a) memset(a,0,sizeof(a))
#define unq(a) sort(all(a)),a.erase(unique(all(a)),a.end())

typedef complex<double> P;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vst;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vector<int> > mat;

const ll inf = (ll)1e9+10;
const ll linf = (ll)1e18+10;
const ll mod = (ll)(1e9+7);
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const int ddx[] = {0, 1, 1, 1, 0, -1, -1, -1};
const int ddy[] = {1, 1, 0, -1, -1, -1, 0, 1};
const double eps = 1e-10;

ll mop(ll a,ll b,ll m=mod) {ll r=1;a%=m;for(;b;b>>=1){if(b&1)r=r*a%m;a=a*a%m;}return r;}
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b) {return a*b/gcd(a,b);}
bool ool(int x,int y,int h,int w) {return((x<0)||(h<=x)||(y<0)||(w<=y));}
bool deq(double a,double b) {return abs(a-b)<eps;}

struct oreno_initializer {
	oreno_initializer() {
		cin.tie(0);
		ios::sync_with_stdio(0);
	}
} oreno_initializer;

// ━━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…
// .｡.:( ^ω^)・ﾟ＋.｡.:( ^ω^)・ﾟ＋.｡.:( ^ω^)・ﾟ＋.｡.:( ^ω^)・ﾟ＋.｡.:( ^ω^)・ﾟ＋
// ・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・‥…━━━☆・

int t, n;
string s, S[10] = {"",".,!? ","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};

signed main() {
	cin >> t;
	rep(T,t) {
		cin >> s;
		n = s.size();
		string res;
		char c;
		int l = -1;
		rep(i,n) {
			if (s[i]=='0' && l!=-1) res.pb(c), l = -1;
			else if (s[i]!='0') {
				if (l==-1) l = 0, c = S[s[i]-'0'][0];
				else l++, l %= S[s[i]-'0'].size(), c = S[s[i]-'0'][l];
			}
		}
		cout << res << ln;
	}
}

C++: #include <iostream>
#include <string>
#include <stdlib.h>

using namespace std;

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

int main(){
  int n;
  string input;
  
  cin >> n;
  
  for(int i=0; i<n; i++){
    char output[76] = "";
    cin >> input;
    char num = '0';
    int kaisu = 0;
    int outlength = 0;
    
    for(int j=0; j<(int)input.length(); j++){
      if(input[j] != '0'){
	num = input[j];
	kaisu++;
      }else if(input[j] == '0' && kaisu != 0){
	output[outlength] = s[atoi(&num)-1][(kaisu-1)%s[atoi(&num)-1].length()];
	kaisu = 0;
	num = '0';
	outlength++;
      }
    }
    output[outlength] = '\0';
    cout << output << endl;
  }
  return 0;
}

C++: // includes {{{
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<tuple>
#include<cmath>
#include<random>
#include<cassert>
#include<bitset>
#include<cstdlib>
// #include<deque>
// #include<multiset>
// #include<cstring>
// #include<bits/stdc++.h>
// }}}
using namespace std;
using ll = long long;

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

int main() {
  std::ios::sync_with_stdio(false), std::cin.tie(0);
  int n;
  cin >> n;
  for(int i = 0; i < n; i++) {
    string t;
    cin >> t;

    int key = 0;
    char now = 0;
    for(char c : t) {
      if(c == '0') {
        if(now) cout << now;
        now = 0;
        key = 0;
      } else {
        auto f = s[c - '0'];
        now = f[key];
        key++;
        key %= f.size();
      }
    }
    cout << "\n";
  }
  return 0;
}

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

int N;
char phone[9][6] = {".,!? ","abc","def","ghi","jkl", "mno", "pqrs", "tuv","wxyz"};

int main(){
  cin >> N;
  
  for(int i=0; i<N; ++i){
    char input[1025];
    cin >> input;
    char old = '0';
    int count = 0;
    for(int j=0; input[j] != '\0'; ++j){
      if(input[j] == '0'){
        if(old != '0'){
          if('2' <= old && old <= '6'){
            putchar(phone[old-'1'][(count-1)%3]);
          }
          else if(old == '1'){
            putchar(phone[old-'1'][(count-1)%5]);
          }
          else{
            putchar(phone[old-'1'][(count-1)%4]);
          }
        }
        old = input[j];
        count = 0;
      }else{
        old = input[j];
        count++;
      }
    }
    cout << endl;
  }
  return 0;
}