• ベストアンサー

何故オーバーフロー??

http://oshiete1.goo.ne.jp/qa4423673.html さらに続きになります。 #include<stdio.h> #include<string.h> #define NAME 256 // 暫定的に最大値を決めてます int Convert(const char* pInFileName, const char* pOutFileName); int ReConvert(const char* pInFileName, const char* pOutFileName); int main(){ int a,ret=-1; char InFileName[NAME]; // 入力ファイル名 char OutFileName[NAME]; // 出力ファイル名 FILE *pInFileName; // 入力ファイルポインタ FILE *pOutFileName; // 出力ファイルポインタ printf("1:コンバート 2:リコンバート\n"); scanf("%d",&a); /***** 入力ファイル名入力 *****/ printf("\n@@@@@入力ファイル名入力\n"); scanf("%s",&InFileName); // 入力ファイルオープン if((pInFileName=fopen(InFileName,"rb"))==NULL){ printf("ファイルがありません\n"); return -1; } /***** 出力ファイル名入力 *****/ printf("\n@@@@@暗号化後ファイル名入力\n"); scanf("%s",&OutFileName); // 出力ファイルオープン if((pOutFileName=fopen(OutFileName,"r"))!=NULL){ // read出来るのなら既にファイルあるという事なのでエラーにする printf("同名のファイルが既にあります\n"); return -1; } pOutFileName=fopen(OutFileName,"wb"); // 1:コンバート // 2:リコンバート // 1,2以外:終了 if(a==1){ ret=Convert((const char*)pInFileName,(const char*)pOutFileName); } else if(a==2){ ret=ReConvert((const char*)pInFileName,(const char*)pOutFileName); } if(ret==0){ printf("正常終了\n"); } else{ printf("異常終了\n"); return -1; } printf("数字+エンターで終了します\n"); scanf("%d",&a); fclose(pOutFileName); fclose(pInFileName); return 0; } /*****コンバート*****/ int Convert(const char* pInFileName, const char* pOutFileName) { unsigned char moji; while(1) { if(fread( &moji, 1, 1, (FILE*)pInFileName )>0){ fprintf((FILE*)pOutFileName,"%02x",moji); } else break; } return 0; } /*****リコンバート*****/ int ReConvert(const char* pInFileName, const char* pOutFileName) { char moji16[3]; // 16進表記 char moji10[4];★★★★★★★★★★ long i,j; while(1) { if(fread( moji16, 1, 2, (FILE*)pInFileName )>0){ for(i=0,j=0;i<2;i+=2,j++){ sscanf(&moji16[i], "%2x", moji10); } fprintf((FILE*)pOutFileName,"%c",moji10); } else break; } return 0; } 上記の char moji10[4];★★★★★★★★★★ の部分ですが、これを配列を用いずに、moji10とした場合(応じてsscanfでは&moji10になる)や moji10[2]、moji10[3]とした場合でもオーバーフローが検出されました。 sscanfの行になった時に、moji10[0]には文字が入りますが、 moji10[1]~moji10[3]まで、NULL文字'\0'が入っていました。 何故moji10[4]にしないとオーバーフローが消えないのでしょうか? 尚、Visual C++ 2008です。

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

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

「数値」を取り込むのに「文字列」を使うと訳がわからなくなりますよ。 あとsscanf()をくくる謎のforループがありますが、条件や処理内容を見る限り不要でしょう。 -- example -- int value; char data; ... sscanf(moji16, "%2x", &value); data = value & 0xff; ... -- overflow検出の原因は、sscanfの%xが32bit値(long)を想定しているのに受け側にそれだけの大きさがなかったためでしょう。

その他の回答 (1)

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

って~か, scanf の変換指定 %x は (signed または unsigned の) int を要求するから, char の配列を使って時点でアウトなんだけど.... moji10[4] にしてオーバーフローが消えたとしても, 「正しくないプログラム」であることに違いはありません. たとえ動いているように見えても.

関連するQ&A

専門家に質問してみよう