質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

5回答

11036閲覧

ファイルに16個ごとに改行を書き込みたい。C言語。

AnywhereGorilla

総合スコア13

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2016/04/07 00:37

ファイルのバイナリを読み込んで、そのバイナリをファイルに16個書き込んだら改行を書き込みたいのですが、うまい方法が見つかりません。

C言語でvisual stdioです。
分かる方いましたら、よろしくお願いします!

#include <string.h> #include <stdio.h> #include <stdlib.h> void BinaryMake(FILE *ifp, FILE *ofp) { fseek(ifp, 0L, SEEK_END); long fsize = ftell(ifp); fseek(ifp, 0L, SEEK_SET); unsigned char *BinaryText = malloc(fsize); fread(BinaryText, sizeof(*BinaryText), fsize, ifp); int i = 0; fprintf(ofp, "Binary Out.\n\n"); // Make BinOut. fprintf(ofp, "unsigned char BinOut[] = {\n"); for (i = 0; i < fsize; i++) { fprintf(ofp, "0x%X, ", BinaryText[i]); // 16の倍数で改行をファイルに書き込みたい。 if (i != 0) { if (i > 16) { if (i % 16 == 0) { fprintf(ofp, "\n"); } } else if (i % 15 == 0) { fprintf(ofp, "\n"); } } } fprintf(ofp, "\n};\n\n"); // BinOutLen. fprintf(ofp, "unsigned int BinOutLen = "); fprintf(ofp, "%d", i); fprintf(ofp, ";\n"); free(BinaryText); } int main(int argc, char *argv[]) { FILE *fIN; FILE *fOUT; errno_t error; char buf[255 + 1]; if ((error = fopen_s(&fIN, "C://Projects/test_curl/Debug/StinkyShitInDaMazafaka.txt", "rb")) != 0) { strerror_s(buf, 255, error); printf("fopen_s error one \n%s\n", buf); return 0; } if ((error = fopen_s(&fOUT, "C://Projects/test_curl/Debug/MazafakaInDaBinSource.txt", "w+")) != 0) { strerror_s(buf, 255, error); printf("fopen_s error two \n%s\n", buf); return 0; } BinaryMake(fIN, fOUT); fclose(fIN); fclose(fOUT); return 0; }

上のソースでファイルに書き込んだ内容の一部です。
2行目が17個目で改行が書き込まれています。
よろしくお願いします!

unsigned char BinOut[] = { 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F,

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

こんな手もある。

// Make BinOut. fprintf(ofp, "unsigned char BinOut[] = {"); for (i = 0; i < fsize; i++) { if (i % 16 == 0) { fprintf(ofp, "\n"); } fprintf(ofp, "0x%X, ", BinaryText[i]); } fprintf(ofp, "\n};\n\n");

追記:誰かが「余計なカンマは出さない」と言うので

// Make BinOut. fprintf(ofp, "unsigned char BinOut[] = {"); char[2] delim = ""; for (i = 0; i < fsize; i++) { fprintf(ofp, delim); if (i % 16 == 0) { fprintf(ofp, "\n"); } fprintf(ofp, "0x%X", BinaryText[i]); strcopy(delim, ", "); } fprintf(ofp, "\n};\n\n");

以上、行頭判断形式。

投稿2016/04/07 01:04

編集2016/04/07 04:08
tkturbo

総合スコア5572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tkturbo

2016/04/07 09:46

strcopyのオーバーヘッドがわからんけど「無駄な出力しない」版も追記してみました。
guest

0

余分なスペースとか改行は許しません。

c

1fprintf(ofp, "unsigned char BinOut[] = {\n"); 2for (i = 0; i < fsize; i++) 3{ 4 //16個目と最後は改行 5 fprintf(ofp, "0x%02X,%c", BinaryText[i], (i%16==15||i==fsize-1)?'\n':'\0'); 6} 7fprintf(ofp, "};\n\n");

投稿2016/04/07 01:43

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AnywhereGorilla

2016/04/07 02:13

僕がやりたかったことができてます!!!回答ありがとうございました!勉強します!
guest

0

あまり難しく考えずに「16個毎に改行する」というのをそのままコードにすれば良いです。

ただ、単純に16個出力したら改行すると、データの数がちょうど16の倍数の時に空行が出力されるので、見栄えを考えてこんな感じでしょうでしょうか。

C

1fprintf(ofp, "unsigned char BinOut[] = {\n"); 2for (i = 0; i < fsize; i++) { 3 fprintf(ofp, "0x%X, ", BinaryText[i]); 4 if(i % 16 == 15 || i == fsize - 1) // 16個出力するか最後のデータを出力したら改行 5 fprintf(ofp, "\n"); 6} 7fprintf(ofp, "};\n\n"); // 先頭の改行は不要

あるいは、改行の位置を工夫するとif文が簡単になります。

C

1fprintf(ofp, "unsigned char BinOut[] = {"); // 最初の行では改行しない 2for (i = 0; i < fsize; i++) { 3 if(i % 16 == 0) // 改行してから16個並べる感じ 4 fprintf(ofp, "\n"); 5 fprintf(ofp, "0x%X, ", BinaryText[i]); 6} 7fprintf(ofp, "\n};\n\n");

投稿2016/04/07 01:30

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

catsforepaw

2016/04/07 01:35

2番目はすでに tkturbo さんが回答したのと同じでしたね。
guest

0

この辺り、「16個かいたら1回改行」に対して条件判定が多すぎます。

C

1 // Make BinOut. 2 fprintf(ofp, "unsigned char BinOut[] = {\n"); 3 for (i = 0; i < fsize; i++) { 4 fprintf(ofp, "0x%X, ", BinaryText[i]); 5 // 16の倍数で改行をファイルに書き込みたい。 6 if (i != 0) { 7 if (i > 16) { 8 if (i % 16 == 0) { 9 fprintf(ofp, "\n"); 10 } 11 } else if (i % 15 == 0) { 12 fprintf(ofp, "\n"); 13 } 14 } 15 16 } 17 fprintf(ofp, "\n};\n\n");

if (i % 16 == 0) 改行 は心情として正しいです。

if (i != 0) は、0 % 16 == 0 になってしまうのを防ぐためだと思いますが、
ここにガードを入れるよりも、最初からi==0 にならないようにする、つまりiを1から
始めるほうが効果的です。if文が1つ減ります。

if (i % 15 == 0)も、0から初めて16回書いたら改行、のために入っているのかな?と
思いますが、iが1から始まれば不要です。

ということで、こういうのはいかがでしょうか。

C

1for (i = 1; i <= fsize; i++) { 2 fprintf(ofp, "0x%X, ", BinaryText[i-1]); 3 if (i % 16 == 0) { 4 fprintf(ofp, "\n"); 5 } 6}

テストはしていません。

投稿2016/04/07 01:09

tnd-.-b

総合スコア247

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AnywhereGorilla

2016/04/07 01:49

気持ちを汲んだ回答ありがとうございました!!!
guest

0

ベストアンサー

こんにちは。

テストしてませんが、たぶん下記でいけると思います。

C

1// Make BinOut. 2fprintf(ofp, "unsigned char BinOut[] = {\n"); 3for (i = 0; i < fsize; i++) { 4 fprintf(ofp, "0x%X, ", BinaryText[i]); 5 // 16の倍数で改行をファイルに書き込みたい。 6 if ((i % 16) == 15) 7 { 8 fprintf(ofp, "\n"); 9 } 10} 11fprintf(ofp, "\n};\n\n");

【追記】
catsforepawさんの回答を見て気が付きました。,が最後についてしまいますね。
もし、生成されたファイルをコンパイルするようでしたら、コンパイラ(例えばVisual strudio)によっては適切にコンパイルしてくれないことがあります。

フラグが必要になることが難点ですが、このような','等を省略したい時、結構使えます。

C

1// Make BinOut. 2fprintf(ofp, "unsigned char BinOut[] = {\n"); 3bool first=true; 4for (i = 0; i < fsize; i++) { 5 if (first) { 6 first=false; 7 } else { 8 // 16の倍数で改行をファイルに書き込みたい。 9 if ((i % 16) == 0) { 10 fprintf(ofp, "\n"); 11 } 12 fprintf(ofp, ", "); 13 } 14 fprintf(ofp, "0x%X", BinaryText[i]); 15} 16fprintf(ofp, "\n};\n\n");

tkturbotさんとcatsforepawさんの回答を見ても感じるかと思いますが、「継続処理」は「本処理」の後で実行するのではなく、「本処理」の前で実行した方が「綺麗」に書けることが多いようです。
そして、最初だけは「継続処理」が不要になるので、それを運良くごまかせない場合は、フラグを使って分岐するのが良さそうです。


理想は、フラグを使わないでループ先頭の処理を分けることができると良いのです。
どなたか良い方法をご存知でしたら是非教えて下さい。

投稿2016/04/07 00:40

編集2016/04/07 01:52
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AnywhereGorilla

2016/04/07 01:48

できました!ありがとうございました!!!
Chironian

2016/04/07 01:53

あっと、追記が間に合いませんでした。 もし,','でハマったら参考にされて下さい。
AnywhereGorilla

2016/04/07 01:59

分かりました!ありがとうございました!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問