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

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

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

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

Q&A

解決済

2回答

3022閲覧

プログラムbcopyはコンパイルできるのですが

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2016/01/24 09:13

編集2016/01/24 09:27

プログラムbcopyでコンパイルできるのですがうまくコピーできません。ファイルLACKNUM2.DAT(44バイト)をファイルLACKNUM3.DATにコピーしてもファイルLACKNUM3.DAT(0バイト)となっています。教科書どおりに打ち込んでいるんですが。どこが悪いのでしょうか。

/* bcopy … ファイルのコピー */ #include <stdio.h> #include <strings.h> #define BSIZE 128 // この大きさ(128byte)に分割してコピー int main(int argc, char *argv[]) { int n; FILE *src, *dst; // *srcと *dstはファイルポインタ unsigned char buf[BSIZE]; if (argc != 3) { fprintf(stderr, "パラメータが不正です。\n"); fprintf(stderr, "bcopy コピー元ファイル名 コピー先ファイル名\n"); } else { if ((src = fopen(*++argv, "rb")) == NULL) { // *++argv=const char *filenameも ,"rb"=const char *modeもポインタ // *argvはコピー元ファイル名 fprintf(stderr, "ファイル%sがオープンできません。\n", *argv); return (1); } else if ((dst = fopen(*++argv, "wb")) == NULL) { // *argvはコピー先ファイル名 fprintf(stderr, "ファイル%sがオープンできません。\n", *argv); fclose(src); return (1); } else { while ((n = fread(buf, BSIZE, 1, src)) > 0) { //コピー元ファイル名(src)からbufに読み込む // ファイルポインタsrcから BSIZE バイトのデータを // 1 個読み込み、読み込みデータ格納先のポインタbufに格納する */ fwrite(buf, n, 1, dst); //bufからコピー先ファイル名(dst)に読み込む } fclose(src); fclose(dst); } } return (0) } 実行結果 ...@naka ~ $ gcc -o bcopy bcopy.c -Wall ...@naka ~ $ bcopy LACKNUM2.DAT LACKNUM3.DAT ...@naka ~ $ ```

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

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

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

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

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

guest

回答2

0

これ、よく初心者がハマるところです。

freadのリファレンス(MSDNより)をよーーーく見てみましょう。

以下抜粋

size_t fread( void *buffer, size_t size, size_t count, FILE *stream );

パラメーター
buffer
データの格納場所。
size
項目のバイト単位のサイズ。
count
読み取る項目の最大数。
stream
FILE 構造体へのポインター。

戻り値
fread で エラーが発生したり、ファイルの末尾に到達する countの前に発生した実際に読み込まれる count 未満である、完全な項目数を返します。

戻り値の「項目数」って……。

つまりこういうことです。

n = fread(buf, BSIZE, 1, src)
fwrite(buf, n, 1, dst);

fread関数でBSIZEバイトのデータを「1個」読み込み、成功したので「1個読んだよ」という意味で「1」が返されます。そして結果的fwrite関数に「1バイトのデータを1個書け」というふうに引数が渡されるので、期待通りに動かないというわけです。

fread、fwriteには、第2引数に1を、サイズは第3引数に指定するというのが定石です。これだと、1バイトのデータをBSIZE個読み込む、あるいは書き込む、という意味になり、期待通りに動くようになります。


追記
すみません。ちょっと見落としていましたコピー先「LACKNUM3.DAT」が0バイトですね。

#define BSIZE 128

前述のfreadで128バイトのデータを1個読むように指定していますが、srcのファイルが128バイトに満たず、結果的に「読めなかった」ので「0」が返されますね。

対処方法は前述の通りです。バイト単位で処理できるようにすることで、そのような問題も回避できます。

投稿2016/01/24 09:29

編集2016/01/24 09:40
catsforepaw

総合スコア5938

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

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

退会済みユーザー

退会済みユーザー

2016/01/24 10:12

ありがとうございます。おっちょこちょいで申し訳ありません。 freadを何回も読み直していたんですが、気が付きませんでした。 この前のプログラムでfprintfのformatで分からないところがあり、 疲れていました。
guest

0

ベストアンサー

最後のreturn;が無いので、コンパイルエラーになるはずです。

また、下記のようにfreadfwriteの引数を変更して下さい。

C

1while ((n = fread(buf, 1, BSIZE, src)) > 0) { 23fwrite(buf, 1, n, dst);

あと、returnの値に無用な括弧を付けないようにしましょう。

これが教科書通りなのであれば、良くない教科書ですね。

投稿2016/01/24 09:36

編集2016/01/24 09:47
otn

総合スコア84538

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

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

otn

2016/01/24 09:51

勘違いがあったので訂正しました。
退会済みユーザー

退会済みユーザー

2016/01/24 10:05

ありがとうございます。これからもちょくちょくお世話になると思います。 よろしくおねがいします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問