- ベストアンサー
テキストファイルをバイナリファイルに変換
-32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, 130, 120, 120, 109, 100, 100, 94, 91, 90, 89, 87, -32768, 78, 71, … と続いていくテキストファイルのデータをバイナリデータにC言語で変換したいのですが、どうすれば変換出来るのでしょうか。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
大体こんな感じですか? おそらくtxtをbinに変換したい、変換形式は-32768→8000といった類の変換ですよね。 既にある回答は、16進データが文字列のまま出力されてしまうのでちょっと不便かもしれません。 (フォーマットが%04Xだったら桁数固定なので、それで良いかもしれませんが。) usage: ./a.out Binary.txt Binary.bin グローバルで宣言されているByte,Signed,LittleEndianの値をいじって変換形式を変えてみてください。 //------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> int Byte=2; bool Signed=true; bool LittleEndian=true; void StrToBinary(char *Str,FILE *fp) { int iwt; unsigned char wBuffer[4]; iwt=atoi(Str); if(Byte<4 && Signed && iwt>(2<<(Byte*8-1))-1) iwt=(2<<(Byte*8-1))-1; if(Byte<4 && Signed && iwt<-(2<<(Byte*8-1))) iwt=-(2<<(Byte*8-1)); if(Byte<4 && !Signed && iwt>(2<<(Byte*8))-1) iwt=(2<<(Byte*8))-1; if(!Signed && iwt<0) iwt=0; for(int j=0;j<Byte;j++) { if(LittleEndian) wBuffer[j]=((unsigned char *)(&iwt))[j]; else wBuffer[Byte-j-1]=((unsigned char *)(&iwt))[j]; } fwrite(wBuffer,1,Byte,fp); } int main(int argc,char *argv[]) { char valBuffer[64]; int i=0; bool IsInt,IsNumber; FILE *fp_r; FILE *fp_w; if(argc<=2) { printf("Invalid parameters."); return 0; }else{ fp_r=fopen(argv[1],"r"); fp_w=fopen(argv[2],"wb"); } if(fp_r==NULL) { printf("Read failed. - %s",argv[1]); return 0; } if(fp_w==NULL) { printf("Write failed. - %s",argv[2]); fclose(fp_r); return 0; } i=0; IsInt=true; while(!feof(fp_r)) { valBuffer[i]=fgetc(fp_r); IsNumber=false; if(i==0 && valBuffer[i]=='-') IsNumber=true; if(IsInt && valBuffer[i]=='.') { IsNumber=true; IsInt=false; } if(valBuffer[i]>='0' && valBuffer[i]<='9') IsNumber=true; if(IsNumber) i++; else{ if((valBuffer[0]!='-' && valBuffer[0]!='.' && i==1) || i>1) { valBuffer[i]=0; StrToBinary(valBuffer,fp_w); } i=0; IsInt=true; } } if((valBuffer[0]!='-' && valBuffer[0]!='.' && i==1) || i>1) { valBuffer[i]=0; StrToBinary(valBuffer,fp_w); } fclose(fp_r); fclose(fp_w); printf("Conversion succeed. - %s",argv[1]); return 0; }
その他の回答 (5)
- _--_1l1_1_
- ベストアンサー率67% (102/152)
適当。すでに回答があるけど、とりあえす。 表示がくずれるので空白 2 文字を全角空白 1 文字にしていることに注意。 #include <stdio.h> #include <error.h> #define READ_BUF_LEN 128 int main(int argc, char *argv[]) { char *input_file = "input.txt"; char *output_file = "output.bin"; FILE *fp_in, *fp_out; char buf[READ_BUF_LEN]; int pos, num; fp_in = fopen(input_file, "r"); if (NULL == fp_in) { perror(input_file); return; } fp_out = fopen(output_file, "w"); if (NULL == fp_in) { perror(output_file); return; } pos = 0; while (!feof(fp_in)) { buf[pos] = fgetc(fp_in); if (ferror(fp_in)) { perror(input_file); break; } else if ( ((pos == 0) && (buf[pos] == '-')) || isdigit(buf[pos]) ) { if (pos > (sizeof(buf) - 1)) { perror("Buffer over"); break; } pos++; } else if ((buf[pos] == ',') || (buf[pos] == EOF)) { buf[pos] = '\0'; sscanf(buf, "%d", &num); fwrite(&num, sizeof(num), 1, fp_out); pos = 0; } else { /* Skip other character */ } } fclose(fp_in); fclose(fp_out); return 0; }
お礼
なんとかなりそうです。 ありがとうございます!
- 和泉 博(@hiroshi09s)
- ベストアンサー率54% (59/109)
#2 です。 ほとんど回答したも同然なのですが、なかなか応答がないようです。 改良点は、記録領域として「 short v[1024] 」の変数を加えたことと、printf()に換わって出力に write() 低水準入出力関数を用いたことです。その他のプログラム内容は変わっておりませんので解説は割愛させていただきます。 Linux などの UNIX系は、 ./a.out<bainary.txt>bainary.bin とし、作成されたバイナリーファイルは od<bainary.bin -t d2 を実行して、↓の通り表示されることを確認してください。 ----- od<bainary.bin -t d2 ----- 0000000 -32768 -32768 -32768 -32768 -32768 -32768 -32768 -32768 0000020 -32768 -32768 130 120 120 109 100 100 0000040 94 91 90 89 87 -32768 78 71 0000060 ----- od<bainary.bin -x ----- 0000000 8000 8000 8000 8000 8000 8000 8000 8000 0000020 8000 8000 0082 0078 0078 006d 0064 0064 0000040 005e 005b 005a 0059 0057 8000 004e 0047 0000060 ----- bainary.txt テキストファイル ----- -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, 130, 120, 120, 109, 100, 100, 94, 91, 90, 89, 87, -32768, 78, 71, /* Gcc on Mac OSX */ #include <stdio.h> #include <stdlib.h> #define STDOUT 1 #define SHORT_SIZE 2 int main(void) { int i,c,n,count=0; char buffer[12]; short v[1024]; //←2バイト格納領域 n=0; while((c=getchar())!=EOF){ if(!(c==',' || c==' ' || c=='\n')){ buffer[n]=c; n++; } else if(n){ buffer[n]='\0'; v[count]=(short)atoi(buffer); //printf("%x ", atoi(buffer)); n=0; count++; } else ; } fprintf(stderr,"Write count= %d(%d data) byte\n", write(STDOUT,v,SHORT_SIZE*count), count); for(i=0;i<count;i++) fprintf(stderr,"%d ", v[i]); fprintf(stderr,"\n"); return 0; }
お礼
何とかなりそうです。 ありがとうございます。
- D-Matsu
- ベストアンサー率45% (1080/2394)
既出回答の通りすべてのファイルはバイナリデータであって、「テキストファイル」というのは扱う側の都合でカテゴリしているに過ぎません。 まぁおそらく-32768⇒0xFFFFという感じで変換したいのだとは思うのですが、最終結果をどうしたいのかをはっきりさせてください。 要するに、このファイルをどういう形のデータとして持ちたいのか、ということです。 なお文字列⇒数値変換についてはatoiよりはエラー検出できるsscanfかstrtolの方がいいです。
お礼
参考にします。 ありがとうございます!
- 和泉 博(@hiroshi09s)
- ベストアンサー率54% (59/109)
好みに応じて「 printf("%x ", atoi(buffer)); 」の書式を変えてください。 Linux などの UNIX系は、 ./a.out<bainary.txt とコマンドラインからリダイレクト入力すればOKです。 ----- bainary.txt ----- -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, 130, 120, 120, 109, 100, 100, 94, 91, 90, 89, 87, -32768, 78, 71 /* Gcc on Mac OSX */ #include <stdio.h> #include <stdlib.h> int main(void) { int c,n; char buffer[12]; n=0; while((c=getchar())!=EOF){ if(!(c==',' || c==' ' || c=='\n')){ buffer[n]=c; n++; } else if(n){ buffer[n]='\0'; printf("%x ", atoi(buffer)); n=0; } else ; } printf("\n"); return 0; } ----- 実行結果 ----- ffff8000 ffff8000 ffff8000 ffff8000 ffff8000 ffff8000 ffff8000 ffff8000 ffff8000 ffff8000 82 78 78 6d 64 64 5e 5b 5a 59 57 ffff8000 4e 47
お礼
何とかなりそうです。 ありがとうございます!
- kmee
- ベストアンサー率55% (1857/3366)
逆にお聞きしますが、これをどんなバイナリデータに変換したいのですか? コンピュータのほぼ全てのファイルは「バイナリファイル」でもあるのですが。 (質問の例でも、 '-'の文字を表すバイナリデータ、'3'の文字を表すバイナリデータ、'2'の文字を表すバイナリデータ .... というバイナリデータ列のファイルと解釈することもできます。)
お礼
参考にします。 ありがとうございます。
お礼
何とかなりそうです。 ありがとうございます!