演習11ー12
問: atoi関数、atol関数、atoll関数、atof関数と同じ仕様の関数を作成せよ。
// Ex1112.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include <stdio.h>
#include <limits.h>
#define CHARSIZE 128
long long null_bullets(int n)
{
long long s_bullet = 1;
if (n > 1) {
while (n != 1) {
s_bullet = s_bullet * 10;
n--;
}
}
return s_bullet;
}
double olignal_atoX(char* ati)
{
int len1 = strlen(ati);
int hyphen_c = 0;
int decimal_c = 0;
int digit_f = 0;
int digit_b = 0;
int digit_s1 = 0;
int digit_s2 = 0;
long long isum = 0;
int tmp_msb = 0;
long long tmp = 0;
double dsum = 0;
// ハイフンチェック
if (ati[0] == '-') {
hyphen_c = 1; //ハイフンがあれば1にする
*ati++; //ハイフンがあれば取る
}
// 改めて小数点チェック()
int len2 = strlen(ati);
// 小数点チェック
for (int i = 0; i < len2; i++) {
if (ati[i] == '.') {
decimal_c = 1; //小数点があれば1にする
digit_f = i; //小数点があった桁(前から)を保全
digit_b++; //総桁数を保全
}
else {
digit_b++;
}
digit_s1 = digit_b - digit_f; //小数点があった桁(後ろから)を保全
}
// 小数点より右側の値を左1桁にずらして小数点を潰す
if (decimal_c == 1) { //小数点があれば実行
digit_s2 = digit_f; //小数点の位置を保全
digit_b = digit_b - digit_s2; //小数点から右側の桁数を取得
for (int i = 0; i < digit_b; i++) {
ati[digit_s2] = ati[digit_s2 + 1];
digit_s2++;
}
}
//ここまででハイフンと小数点が取り除かれている。
//ハイフンの有無と小数点の位置は保全されている。
//改めて桁数チェック
int len3 = strlen(ati);
int cnt = len3;
//文字列を整数に変換
for (int i = 0; i < len3; i++) {
tmp_msb = *ati - '0'; //最上桁のみ取得
isum = isum + (tmp_msb * null_bullets(cnt--)); //最上桁を持ってヌルバレットへ旅立つ
*ati++; //次の桁へ
}
//ここまでで文字列を数値に変換できた
// ハイフン付きだった場合、自分で自分を引いて、自分の分身に更に惹かれて同じ値のマイナスをつくる。
if (hyphen_c == 1) {
tmp = isum;
isum = isum - isum;
isum = isum - tmp;
}
//小数点付きだった場合、値を保全した桁数×ゼロバレットで割って小数点をつける
if (decimal_c == 1) {
dsum = isum;
dsum = (dsum / null_bullets(digit_s1));
return dsum;
}
return isum;
}
int main(void)
{
char str[CHARSIZE] = { 0 };
char str_atoi[CHARSIZE] = { 0 };
char str_atol[CHARSIZE] = { 0 };
char str_atoll[CHARSIZE] = { 0 };
char str_atof[CHARSIZE] = { 0 };
//printf("int : %d 〜 %d\n", INT_MIN, INT_MAX);
//printf("long : %ld 〜 %ld\n", LONG_MIN, LONG_MAX);
//printf("long long : %lld 〜 %lld\n", LLONG_MIN, LLONG_MAX);
//printf("double : %lf 〜 %lf\n", DBL_MIN, DBL_MAX);
//putchar('\n');
printf("文字列を入力せよ:");
scanf("%s", str, 128);
for (int i = 0; i < CHARSIZE; i++) {
str_atoi[i] = str[i];
}
for (int i = 0; i < CHARSIZE; i++) {
str_atol[i] = str[i];
}
for (int i = 0; i < CHARSIZE; i++) {
str_atoll[i] = str[i];
}
for (int i = 0; i < CHARSIZE; i++) {
str_atof[i] = str[i];
}
printf("[atoi]\n");
printf("atoi(str_atoi) = %d\n", atoi(str_atoi));
printf("olignal_atoi(str_atoi)) = %d\n", (int)olignal_atoX(str_atoi));
putchar('\n');
printf("[atol]\n");
printf("atol(str_atol)) = %ld\n", atol(str_atol));
printf("olignal_atoi(str_atol) = %ld\n", (long)olignal_atoX(str_atol));
putchar('\n');
printf("[atoll]\n");
printf("atoll(str_atoll) = %lld\n", atoll(str_atoll));
printf("olignal_atoi(str_atoll) = %lld\n", (long long)olignal_atoX(str_atoll));
putchar('\n');
printf("[atof]\n");
printf("atof(str_atof) = %lf\n", atof(str_atof));
printf("olignal_atoi(str_atof) = %lf\n", (double)olignal_atoX(str_atof));
return(0);
}
コメント
これは今までやった中で一番やりがいがあった問題。楽しかった!
全章の基本的なことを総動員しなければ書けないコードなのでぜひ自力でやってほしい。
ちなみに私のコードは全く最適ではなく、動きの視覚化を優先したものなので、どう手をつけていいかわからない方のみ参考にしてください。
書籍情報
コメント