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

C++: #include<bits/stdc++.h>
using namespace std;

int main(){
  int n;
  string bottan[]={
    "",
    ".,!? ", // 1
    "abc", // 2
    "def", // 3
    "ghi", // 4
    "jkl", // 5
    "mno", // 6
    "pqrs", // 7
    "tuv", // 8
    "wxyz", // 9
  };
  int cnt[] = {5,3,3,3,3,3,4,3,4};
  
  cin >> n;
  while(n--){
    string str; cin >> str;
    int len = str.size();
    int cnt1=0,cnt2=0;
    for(int i=0;i<len;i++){
      if(str[i] == '0'){
	if(cnt1 != 0){
	  if(cnt2%cnt[cnt1] == 0){
	    cout << bottan[cnt1][cnt[cnt1]-1];
	  }
	  else {
	    cout << bottan[cnt1][cnt2%cnt[cnt1]-1];
	  }
	}
	cnt1 = 0; cnt2 = 0;
      }
      else {
	if(cnt1 == 0){
	  cnt1 = str[i] - '0';
	  cnt2++;
	}
	else {
	  cnt2++;
	}
      }
    }
    cout << endl;
  }
}