strncpy後のatoiがおかしい

このQ&Aのポイント
  • C++のVS2005で、strncpyを使用して値をコピーした後にatoi関数を使うと、値が正しくならない問題が発生しています。
  • 問題の原因は正確にはわかりませんが、ナル文字が影響している可能性があります。
  • moji変数では正常に動作するため、原因は他の要素にある可能性があります。
回答を見る
  • ベストアンサー

strncpy後のatoiがおかしい

こんにちは。 C++をVS2005でやっています。 atoi関数を使っているんですが、10個の配列strにstrncpyをやると値がおかしくなります。 10個目に'\0'を代入させてやってみても駄目でした。 以下にソースを載せます。 #include <string.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> int main( void ) { char string[256]; char str[10]; char *moji = "12345464"; int l; // using template versions of strcpy_s and strcat_s: strcpy(string, "6877897898"); strcat(string, "strcpy_s"); strcat(string, "and"); // of course we can supply the size explicitly if we want to: strcat(string, "strcat_s!"); strncpy(str, string, 10); l = strtol(str,NULL,10);// 値が違う 6877897898にならない printf("str = %d\n", l); l = atoi(moji); printf("moji = %d\n", l); l = atoi(string);// 値が違う printf("string = %d\n", l); printf("String = %s\n", string); getchar(); return 0; } 表示結果 str = 2147483647 moji = 12345464 string = 2147483647 String = 6877897898 mojiは正常に動作しますから、ナル文字が原因なのかと思ってしまいますが。原因がいまいち分かりません。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

> strncpy(str, string, 10); > l = strtol(str,NULL,10);// 値が違う 6877897898にならない ここで'\0'の問題があるのはおわかりでしょう。 あとは、intの範囲です。 VS2005であれば、intは32bitのはずなので、表現できる範囲は-2147483648~2147483647となります。10桁の整数すべてを表現するには十分ではありません。

DEADSPACE566
質問者

お礼

確かにそうです。 問題が解決しました。 atoi関数の返値がint型なので32bit 2147483648~2147483647は無理ですね。 指摘したとおりにしましたら動作しました。

その他の回答 (1)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

6877897898はint型に格納できる範囲の数字を超えています。 int型は-2147483648~2147483647の範囲までしか格納できません。 その範囲であれば正しく動作すると思います。

DEADSPACE566
質問者

お礼

 6877897898は十桁なんだから億単位で、すでに32bitの範囲外だったことに気づきました。 修正しましたら正常に動作しました。 ありがとうございます。

関連するQ&A

  • atoi

    123と表示されたいんだけど、コンパイルエラーです。 この場合、atoiの引数して、str[3]の文字を入れる変数をもう1つ用意するしかないですか? キャストでうまくできる方法があったら教えてください。 strという変数の"abc123"という文字は変化させたくないんです。 #include <iostream.h> main(){  int i;  char str[] = "abc123";  i = atoi(str[3]);  printf("%d\n", i); }

  • str系関数を使わずに二つの文字を結合する方法

    自分で色々考えていたのですが中々分からなくて・・・ #include<stdio.h> #include<string.h> int moji(char* b1,char *b2) { char b[11]; int x; strcpy(b, b1); strcat(b, b2); x = strlen(b); return x; } main() { char a[4] = "alt"; char b[8] = "recorde"; int c; c = moji(a, b); printf("文字数は%d\n", c); } のプログラムでmoji関数の部分にあるstr~を全部接続節(for)等で作成してポイントで持ってきた文字を連結するにはどうすればいいでしょうか? strに慣れて自分で作れなくならないためにもお力をかしいただけると嬉しいです。

  • C言語の文字列の取り扱いが分かりません

    こんにちは。 C言語で分からないことがあり、質問させていただきました。 学校で、文字列の取り扱いを習いました。 そこで質問なんですが、以下のソースコードをstrcpy , strcat , strcmp , strlen を使わずに書くことってできないですか? 先生に質問したところ、ポインタとかいうのを使うのだそうですが、それを使わずに書くことってできるんですか?もしよろしければお願いします。 以下のプログラムですが、ユーザーから2つの文字列を受けて、そこから4つの文字列関数を使ってみましょう、というやつです。実行結果も貼っておきますね。 #include <string.h> #include <stdio.h> int main(void) { char str1[80], str2[80]; int i; printf("INPUT 1st word-line. : "); gets(str1); printf("INPUT 2nd word-line. : "); gets(str2); /*文字列(word-line)の長さを確認します。*/ printf("%s is %d moji long.\n", str1, strlen(str1)); printf("%s is %d moji long.\n", str2, strlen(str2)); /*文字列を比較します。*/ i = strcmp(str1, str2); if (!i) printf("two word-lines are same length.\n"); else if (i < 0) printf("%s is smaller than %s.\n", str1, str2); else printf("%s is bigger than %s.\n", str1, str2); /*十分なスペースがあるのなら、str2をstr1の最後に結合させます。*/ if((strlen(str1) + strlen(str2)) < 80 ){ strcat(str1, str2); printf("%s\n", str1); } /*str2をstr1にコピーする*/ strcpy(str1, str2); printf("%s %s\n", str1, str2);

  • プログラムの添削

    以下のようなプログラムを作りました.よりよい書き方,アドバイスなどお願いします. /*文字列の入力を繰り返し受け取るプログラムを作成しなさい.*/ #include<stdio.h> #include<string.h> int main(void) { char bigstr[101],str[31]; printf("文字列の入力を繰り返し受け取るプログラムです.\n"); strcpy(str,""); strcpy(bigstr,""); for(;;) { printf("文字列を入力してください.\n"); gets(str); if(strlen(str)>30) { printf("入力できる文字数の上限(20字)を超えました.\n"); return 0; } else if(strcmp(str,"quit")) { strcat(bigstr,str); if(strlen(bigstr)>100) { printf("入力できる文字数の上限(合計100字)を超えました.\n"); return 0; } } else break; } printf("%s\n",bigstr); return 0; }

  • どこがちがうのでしょうか?

    以下の二つのプログラムはユーザーが文字を入力し、80文字以下なら ピリオドを追加して表示するというものです。上はうまくいきますが、下はうまくいきません。なぜでしょうか? #include<string.h> #include<stdlib.h> int main() { char str[80]; int i; printf("文字列を入力してください。\n"); gets(str); if(strlen(str)<80) { for(i=strlen(str);i<79;i++) strcat(str,"."); } printf("%s",str); } #include<stdio.h> #include<string.h> #include<stdlib.h> int main() { char str[80]; int i; printf("文字列を入力してください。\n"); gets(str); if(strlen(str)<80) { for(i=strlen(str)+1;i<79;i++) str[i] = "."; } printf("%s",str); }

  • C言語に詳しい方お願い致しいます

    文字列Aから文字列Bを除いた結果を表示するプログラムなのですが 一ヶ所分からない部分があります。 #include <stdio.h> #include <string.h> int main(void){  char str1[] = "abcdefg";  char str2[] = "cde";  char str3[128] = "";  char *p1 = str1, *p2;  size_t len;  len = strlen(str2);  while((p2 = strstr(p1,str2)) != NULL) {   strncat(str3,p1,p2 - p1);   p1 = p2 + len;   printf("----\n");   printf("p2=%s\n", p2);   printf("str3=%s\n", str3);   printf("p1=%s\n", p1);  }  strcat(str3,p1);  printf("%s\n",str3);  return 0; } while文中の p1 = p2 + len; なのですが、何故これでp1の内容が「fg」になるのでしょう。

  • 構造体での質問!

    a.outの後にid ログイン名 ファミリーネーム ファーストネームを格納して出力するコードを 書いたのですが、これを a.out 5 のように書いて任意の人数の情報を格納して出力するものに したいのですが、↓をどうすればよいのでしょうか?お願いします!! #include <stdio.h> #include <string.h> structstudent { intid; char login[16]; char first[16]; char family[16]; }; intmain(intargc, char *argv[]) { structstudent st, *sp; if (argc!= 5) { printf("usage: %s[id] [login] [Family name] [First name]¥n", argv[0]); exit(‐1); } st.id= atoi(argv[1]); strcpy(st.login, argv[2]); strcat(st.first, argv[3]); strcpy(st.family, argv[4]); sp=&st; printf("id=%d¥n", sp‐>id); printf("loginname=%s¥n", sp‐>login); printf("Name=%s%s¥n", sp‐>first, sp‐>family); }

  • C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問

    C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問です! ファイルを開いた後でエラーとなるのですが、何が足りないのでしょうか? ファイル内容 20 田中 10 鈴木 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp; char str[256]; char *tp; int k,i=0; int num[10]; char na[10][20]; fp=fopen(argv[1],"r"); if(fp==NULL){ printf("ファイルを開けません\n"); return 1; }else{ printf("開けた\n"); } while(fgets(str,sizeof str,fp)!=NULL){ tp=strtok(str," "); num[i]=atoi(tp); tp=strtok(NULL," "); strcpy(na[i],tp); i++; } printf("%d\n%s\n",num[0],na[0]); printf("%d\n%s\n",num[1],na[1]); fclose(fp); return 0; }

  • C言語での文字列ソート動作について

    任意の文字列を入力し、その文字列を昇順にソートするプログラムを作ったのですが、入力する文字の文字数が大きく異なると期待した結果が得られません。 文字数が少なくなったり、他の配列の文字が混ざったりと言う結果に成ってしまっています。 何が原因か分からない状態です。 以下にサンプルを記載させて頂きますので、助言よろしくお願いします。 /*----------------------------------------- 入力例 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC BBBBBBBBBBBBBBBB AAAAAA -----------------------------------------*/ #include <stdio.h> #include <string.h> #include <stdlib.h> void swapc(char *cx , char *cy){ char tmp[100]; strcpy(tmp, cx); strcpy(cx, cy); strcpy(cy, tmp); } int main(){ char *num[100]; char str_tmp[100]; //文字列一時格納 int moji_cnt; //入力した文字列のカウント int n , m; // 文字列入力処理開始 printf("文字列を入力してください\n"); for( moji_cnt = 0 ; moji_cnt != 3 ; moji_cnt++){ scanf("%s", str_tmp); *(num+moji_cnt) = (char *)malloc(sizeof(char) * (strlen(str_tmp)+1)); //メモリ確保 strcpy(*(num+moji_cnt), str_tmp); } puts("\n"); // 文字数ソート処理 for(n = 0 ; n < moji_cnt-1 ; n++){ for(m = 1 ; m < moji_cnt-n ; m++){ if(strcmp(*(num+n) , *(num+n+m)) > 0){ swapc(*(num+n) , *(num+n+m)); // 文字列入れ替え } } } puts("\n"); for(n = 0;n != moji_cnt;n++){ printf("%s\n" , *(num+n)); } free(num); }

  • 文字列のコピー

    C言語で、文字列をコピーする関数で、処理が止まってしまいます。 以下が実行したプログラムです。 #include<stdio.h> #include<string.h> void copy(char *str2 ,char *str3){ strcpy(str2,str3); } void input(char* str){ scanf("%s",str); } int main (void){ char *a; char *b="TEST"; printf("%s\n",b); input(a); copy(b,a); printf("%s",b); return(0);} copy(b,a);で処理が止まってしまいます。入力した文字列を表示できるように、御指摘お願いします。

専門家に質問してみよう