• 締切済み

文字を数値化する方法で詳しく教えて

 すいませんが、C言語わかる方おしえてください。  もともとchar型で例えば  char buf[13]となっているものを  数値化するために、buf[i]-'0'として数値化する。という  記述があるのですが、これで数値化されたことになるのでしょうか? ちなみにこのbuf[13]にはgets(buf)で0~9の数字を自分でいれるので  buf[0]からbuf[13]で数字列がはいります。  別件で  char ac ,buf[13];で  ac=buf[i++]のように記述すると、演算子の+,÷,-,+が決められtるそうなのですが、この記述方法でいいのか判断して欲しいです

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

処理系が限定されていない以上, 「アスキーコード」と勝手に解釈してはいけないのではないでしょうか>#1. もっとも, C で使ういかなる符号系においても「文字 '0' から '9' はこの順に連続している」ことが決まっているのでここだけに限定して言えば「アスキーコード」と仮定しても結果は同じなのですが. ちなみに「数字かどうか」の判断は (ctype.h を #include して) isdigit を使うのが正解.

  • goosyu
  • ベストアンサー率58% (36/62)
回答No.3

> 別件で > char ac ,buf[13];で > ac=buf[i++]のように記述すると、演算子の+,÷,-,+が決められtるそうなのですが、この記述方法でいいのか判断して欲しいです 想定サンプルのようにソースが書かれていることを予測して、”ac = buf[i++];”について説明します。 ”ac = buf[i++];”は単独で「演算子(符号)」を取得出来ません。前後に処理があってはじめて効果を発揮します。 また”ac = buf[i++];”次の内容と同じです。 ac = buf[i]; i = i + 1; acにはbuf[i]が格納され、次の処理の為にiを1つ加算します。 この為、例のような"123+45"であればbuf[3]の'+'をacに格納するためにはiが3になっている必要があります。 ■想定サンプル char buf[256]; int i; int sum; int wk; char ac; gets(buf); sum = 0;      // 初期化 wk = 0; for ( i = 0; '\0' != buf[i]; i++ ) {  // 最初の数値を取得するループ、終了条件はbuf[i]に'\0'が見つかるまで   if ( ( '0' > buf[i] ) || ( '9' < buf[i] ) ) {  // 数字以外が見つかればループから抜けて次の処理へ     break;   }   sum = sum * 10 + buf[i] - '0'; } ac = buf[i++];// 演算子格納 for ( ; '\0' != buf[i]; i++ ) {    // 次の数値を取得するループ、終了条件はbuf[i]に'\0'が見つかるまで   wk = wk * 10 + buf[i] - '0'; } switch(ac) { case '+' :   sum+=wk

yorosi18
質問者

お礼

返信ありがとうございます。  >ac = buf[i];  >i = i + 1;   >例のような"123+45"であればbuf[3]の'+'をacに格納するためにはiが3になっている必要があります  この記述のプログラムは  for(i=0,sum=0;buf[i]>='0' && buf[i]<='9';i++){ sum=sum*10+buf[i]-'0'; ac=buf[i++]; なので123の数字までがsum部分  そしてこのとき+がacに入ると。。。    そして次にfor(wk=0;buf[i]>='0' && buf[i]<='9';i++){ wk=wk*10++buf[i]-'0'; となる。このときwkの部分は45 になる。  全体的に納得できました。深く感謝します。ありがとうございました。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

まず、 >char buf[13]となっているもの この定義では、 >buf[0]からbuf[13]で数字列がはいります。 こうなりません。使えるのは、buf[0]~buf[12]の13要素です。 >数値化するために、buf[i]-'0'として 特定の一桁を数値化するのであれば、この方法でよいです。 buf[]の中身全体を数値化するときにも、ループの中でこの方法を使えばOKです。 が、めんどうなのでatoi() や strtol() のような標準関数を使うことの方が多いと思います。 桁あふれに注意する必要があるとは思いますけれど…。 別件については、何をおっしゃっているか私もわかりません。 buf[]の中身が具体的にどうなっているときに、四則演算子をどうしたいのでしょうか?

yorosi18
質問者

お礼

 詳しい説明ありがとうございます。  配列のところbuf[0]~buf[12]ですね。すいません。  別件ですが  たとえばgets(buf)で123+45みたいに自身でキーボードで  入力したら、変数sum=sum*10+buf[i]-'0'でsumには123が  入力されて  次にac=buff[i++]でこのとき演算子を格納されるらしいのですが  この場合は上のgets(buf)で入力した123+45の+が格納され  次に45の部分はwk=wk*10+buf[i]-'0'でwkには123が  入力される。  そして最後に switch(ac){ case '+': sum += wk; break;で123+45の値を出すようなプログラムです。

回答No.1

あんまり好きではないですが可能です。 char型の中身は入っている文字はアスキーコードというコードで保存されていて、たとえば、「0」は48という数字であらわされます。 「1」は49と順番に増えていきます。 '0'というのは内部的には48と同じですので、「-'0'」は「-48」と同じ意味です。 たとえば、文字として「1」が入っていた場合、内部的には49というコードが入っています。 ここから48を引くと1になり、結果、数値かされたことになります。 本当はatoiという関数を使うのが分かりやすいのですが、関数呼び出し等のオーバーヘッドを気にするような場合はこういう書き方をしていました。 他にも、アルファベットの小文字に32を足して大文字にしたり等、アスキーコード表を利用した文字変換は一昔前には良く使われていました。今でも、組み込み等の低スペックCPU用のプログラミングでは使われているかもしれません。 別件という方は、すみません、良く意味が読み取れませんでした。

参考URL:
http://e-words.jp/p/r-ascii.html
yorosi18
質問者

お礼

 詳しい説明ありがとうございます。  アスキーコードのchar型理解できました。  大丈夫です。  別件ですが、すいません。 ac=buf[i++]のように記述すると演算子が決まるか?  という質問です。

関連するQ&A

  • 文字列数値化

     ちょっとした事情によりint型で作った数字の文字列をC言語で数値化する方法を教えてください。 よろしくお願いします。

  • 関数の型

    C言語の勉強をしております。 以下のように、入力用の関数を作成し、入力された文字列を返して欲しいんですが、「1 番目の引数を 'char *[80]' から 'char *' に変換できません。」という警告メッセージが出てしまい、解決出来ません・・・。 原因と解決策を教えていただけないでしょうか? ちなみに環境はWindowsXP、コンパイラはVC6.0です。 #include <stdio.h> char *insertName(char *buf); int main(void) { char *buf[80]; buf = insertName(buf); printf(buf); return 1; } char *insertName(char *buf) { gets(buf); return buf; } mainの「buf」の定義を「char *buf」にすればエラーは出ないんですが、大きさを指定したいので・・・ どうかよろしくお願いいたします。

  • 文字列を後ろから1文字ずつ表示する

    初歩的なプログラミングです。 C言語の勉強中で、タイトルの通りの プログラムを作りたいのですが、 何かヒントを頂けないでしょうか。 自分で書いてみて失敗したのは下記の 通りです。 char s[11]; int i=0; printf("文字列入力(10文字以内-->)"); gets(s); printf("s=%s",s); while(s[i]!='\0'){ i++; } while(i=0){ printf("%c\n",s[i-1]); i--; } 宜しくお願いします。

  • Cプログラミング(文字入力)

    getsを使って文字を入力し、while文で一文字ずつ 表示させるプログラムをつくりたいのですが、 上手く動作しません。 間違っている点を指摘頂けないでしょうか。 宜しくお願いします。 char c[11]; int i; printf("文字列を入力してください(10文字以内)\n-->"); gets(c); while(i=0;c[i]=='\0';i++){ printf("%c\n",c[i]); }

  • C#で文字列から数値だけ取得する方法

    C#で文字列から数値だけ取得する方法 stringの文字列をcharの文字配列に入れなおして 数値の場合だけ、別の配列(例:a[3])にコピーする。 そんな方法で数値を抜き出そうかと思っています ですが、文字列から数値だけを見つけ出して取得する方法がわかりません。 詳しくのっているサイトなどありましたら 教えてください…!!

  • JavaでC言語のポインタ演算風な使い方は

    Java初心者です。ずっとC言語をやっていました。 Javaにはポインタは存在せず(実際は参照渡しなのでポインタその ものなのですが)、ポインタに対する演算はありませんよね。 C言語で、 int buf[2*10]; int *dst = buf; for(i=0;i<10;i++){ dst[0]=a; dst[1]=b; dst += 2; } のようなソースをJavaで書こうとすると、 for(i=0;i<10;i++){ buf[i*2+0]=a; buf[i*2+1]=b; } しか思いつきません。 コンパイルして最適化されれば問題ないと思いますが、 なんか配列中の演算が演算量をとりそうで、気になっています。 もっと高速に処理されるような書き方はないものでしょうか? アドバイスよろしくお願いします。

    • ベストアンサー
    • Java
  • C言語の課題で困っています;

    C言語の課題で困ってます; 学校の課題で、キーボードから文字を入力する(最大80文字)。入力された文字列と、入力した文字列を逆順にした文字列を表示する。(malloc,freeを使って作成して下さい) ヒントで #invlude <stdio.h> void main(void){ char *buf; //入力文字列用 char *seq; //入力文字列用コピー用 char *rev; //逆順文字列用 int lec, i; buf =(char*)malloc(81); printf("文字列を入力:"); scanf("%s"buf ); for(i = 0; buf[i] ??? '\0'; i++){ } Ien = i; /* lenに文字列の長さが入る */ seq = ???(??? + 1); /* len+1文字文確保*/ for(i = 0; ???; i++){ seq[0] = buf[0]; } free(buf); rey = ???(len + 1); for(i = 0; < len; i++){ rev[len - i - 1] = seq[i]; } ren[i] ~ '\0'; printd("入力文字列 : %s\n",sep); でたんですが、全然分からなくて足りない部分の答えを教えてもらえると助かります;

  • 文字列の入力、数値変換について

    入力された数字を数値に変換するプログラムを作ったのですが、うまくいきません。 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <ctype.h> unsigned long long atollu(char[16]); void main(void){ unsigned long long input; char str[16]; char test[16] = "123456789012345"; int i,j=1; //atollu の動作確認・・・(1) printf("atollu test:%llu\n\n",atollu(test) ); //入力 NG: printf("%d回目 数値を入力(1~100000000000000 終了:exit)>",j); gets(str); input = atollu(str); //str と atollu(str) の確認 printf("%s %llu\n\n",str,atollu(str)); //exitと入力すると終了・・・(2) if(strcmp(str, "exit") == 0){ exit(0); } //数字以外がないか確認・・・(3) else { for( i=0; i<=15; i++){ if(isdigit(str[i]) == 0){ printf("NG\n"); for( i=0; i<=16; i++){ str[i]='\0'; } printf("moji\n"); j++; goto NG; } } } //範囲外 if(input>100000000000000 || input==0){ printf("NG\n"); printf("hani\n"); j++; goto NG; } printf("\n入力値は% llu",input ); } unsigned long long atollu(char str[16]){ unsigned long long t=0; int i,n; n = strlen(str) - 1; for( i=0; i<=15; i++){ if(str[i] == '\0'){ str[i] = 0;} else { t = t + (str[i] - '0') * pow(10.0,n-i);} } str[16] = '\0'; return t; } /* 数字を数値に変換する関数atolluは自分で作りました。 これの動作は(1)でちゃんとした値が出ているのでうまくできているようです。 (2)も"exit"と入力すれば終了するのでうまくいっています。 また、例えば "12" と入力したとき 12 9 NG moji 表示されますが、二回目以降は 12 12 NG moji となり、atollu(str)はうまく出力されている一方で、最後に「moji」と出てきているので、(3)でうまくいっていないようです。 どう直すべきなのか見当もつかないので困っています。 よろしくお願いします。

  • C言語で取得した文字列を、C++の文字列として取り扱いたいです。

    C言語で取得した文字列を、C++の文字列として取り扱いたいです。 皆さんこんにちは。 C言語で取得したchar型で定義された文字列を、 C++の「std::string」に渡したいと思っております。 どうすればかなうでしょうか? 具体的には次のような内容です。 ■C言語側 ---- char key1 = "deperture"; ---- ■C++側で「key1 = key2」としたいです。 ---- std::string key2 = key1; ---- C言語側で記述されている「key1」の値(deperture)を、 C++ソース内の「key2」に渡したいと思っています。 こうゆう場合、どんな方法をとれば適切でしょうか。 C言語側でのchar型の文字列の値を、 C++側の「std::string」型として C++のソースへ渡す方法が分からないです。 アドバイスいただけるとありがたいです。 簡単な例を頂けると更に大変ありがたいです。 以上どうぞ宜しくお願い致します。

  • 数値から2進数の文字列変換

    ある数値を2進数の文字列に変換したい関数を作りたいのですが、うまく出来ません。 2進数表示させるのに、シフト演算を使いたいのですがうまくいきません。 ヒントでもいいのでおしえてください。 ↓いちよう作ろうとしているプログラムです。 char *a(int atai){ int amari; char moji=0; while (atai != 0) { amari = atai % 2; atai = atai / 2; /*2進数表示させたい*/ } return moji;