Shammer's Philosophy

My private adversaria

itoa 実装

atoi はあるが、itoa はない、ということで実装してみた。sprintf を使用すべし、というサイトが多いが、Java からプログラミングを始めた人間としては Java で標準的に使用できていた関数が存在しないのは苦しい。今後使いたくなるシーンも多いと予想されたのが動機。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Number : ASCII Code
// 0      : 48
// 1      : 49
// 2      : 50
// 3      : 51
// 4      : 52
// 5      : 53
// 6      : 54
// 7      : 55
// 8      : 56
// 9      : 57

char * itoa(int x){
    char * value;
    // int max is 2147483647, this is 10 digit.
    int i, j, length, digit, result;
    int rest = abs(x);
    // Check number of digit
    for( i = 10 ; 0 <= i ; i-- ){
	digit = 1;
	for( j = i ; j != 0 ; j-- ){
	    digit = 10 * digit;
	}
	if( (rest / digit) != 0 ){
	    length = i;
	    value = (char *)malloc(sizeof(char) * (length + 1));// 1 means '\0'
	    memset(value, 0, sizeof(value));
	    break;
	}
    }
    // Fill in the char
    for( i = length ; 0 < rest ; i-- ){
	digit = 1;
	for( j = i ; j != 0 ; j-- ){
	    digit = 10 * digit;
	}
	result = rest / digit;
	rest = rest % digit;
	int index = length - i;
	switch (result) {
	    case 0:
		value[index] = '0';
		break;
	    case 1:
		value[index] = '1';
		break;
	    case 2:
		value[index] = '2';
		break;
	    case 3:
		value[index] = '3';
		break;
	    case 4:
		value[index] = '4';
		break;
	    case 5:
		value[index] = '5';
		break;
	    case 6:
		value[index] = '6';
		break;
	    case 7:
		value[index] = '7';
		break;
	    case 8:
		value[index] = '8';
		break;
	    case 9:
		value[index] = '9';
		break;
	    default:
		// Do nothing
		break;
	}
    }
    if( x < 0 ){
	length = strlen(value);
	char temp[length];
	for( i = 0 ; i < length ; i++ ){
	    temp[i] = value[i];
	}
	temp[length] = '\0';
	length = length + 1;// for minus
	free(value);
	value = (char *)malloc(sizeof(char) * (length + 1));//plus 1 is for '\0'
	memset(value, 0, sizeof(value));
	value[0] = '-';
	for( i = 0 ; i < length ; i++ ){
	    // + 1 is for '-'
	    *(value + 1 + i) = temp[i];
	}
    }
    value[length + 1] = '\0';
    return value;
}

int main(int argc, char **args){
    printf("%s\n", itoa(9));
    printf("%s\n", itoa(1234));
    printf("%s\n", itoa(-9999));
    return 0;
}

とりあえず、Integer の範囲、つまり、32bitの範囲。一応、負の数にも対応して、負の数の場合はマイナス付で文字列化することにした。実行結果は以下の通り。

$ ./a.out 
9
1234
-9999
$

テスト不足なところもあるかもしれないが。