ファイルのコピーが上手くいきません。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
hiro

ファイルのコピーが上手くいきません。

#1

投稿記事 by hiro » 18年前

ファイルをコピーするプログラムを作りましたが上手く動作しません。
(コピーしたファイルの内容が変ってしまいます。)

プログラムを以下に示します。

#include <stdio.h>
main(argc,argv)char *argv[/url];
{
FILE *fin;
FILE *fout;
int c;

fin = fopen(argv[1],"r");
fout = fopen(argv[2],"w");

if(fin == NULL)
{
printf("入力ファイル[%s]がオープンできません。\n",argv[1]);
exit(1);
}
if(fout == NULL)
{
printf("出力ファイル[%s]がオープンできません。\n",argv[2]);
exit(1);
}
while((c=getc(fin)) != EOF)
{
putc(c,fout);
putchar(c);
}
fclose(fin);
fclose(fout);
}

上のプログラムに以下の3行のデータファイルを読ませて、画面表示と新しいファイルへの書き出しをさせました。

abcdefghijklmnopqrstuvwxyz
1234567890abcdefghijklmnop
zzzzzzzzzzzzzzzzzzzzzzzzzz


実行方法はDOSプロンプトで fcopy in_file out_file としました。
(fcopyは実行ファイルで、in_fileが上記の入力データファイルです。out_fileは画面と同じものをファイル出力させたものです。)

実行の結果、画面には正常に出力されましたが、out_fileの中身が以下のようになりました。

abcdefghijklmnopqrstuvwxyz^M?????????? 愀戀??攀昀最?椀?????????zzzzzzzzzzzzzzzzzzzzzzzzzz^M?

putcharもputcも同じ出力内容になると思ったのですが...、また、どこがおかしいのでしょうか?

box

Re:ファイルのコピーが上手くいきません。

#2

投稿記事 by box » 18年前

> #include <stdio.h>

exitを呼び出していますので、stdlib.hもインクルードしてください。

> main(argc,argv)char *argv[/url];

コンパイルエラーにこそならないものの、書き方が標準的ではありません。
int main(int argc, char *argv[/url])
あたりがよろしいと思います。

> fin = fopen(argv[1],"r");
> fout = fopen(argv[2],"w");

argcが3以上であるかどうかを判定してから、
argv[1]とargv[2]を参照する方がよいです。

> fclose(fout);

main関数の戻り値は言語規格上int型です。
プログラム終了時に return 0; などとしてください。

指摘した箇所を修正して、もう一度トライしてみてください。

> 実行の結果、画面には正常に出力されましたが、out_fileの中身が以下のようになりました。

なお、当方では、アップロードされたコードを
そのままコンパイルして(警告はいくつか出ましたが)できあがった
実行ファイルを使って、正しくコピーできました。
ご自身のところとどういう違いがあるかは、よくわかりません。

keichan

Re:ファイルのコピーが上手くいきません。

#3

投稿記事 by keichan » 18年前

fin = fopen(argv[1],"rb");
fout = fopen(argv[2],"wb");
とした場合どのような結果になりますか?

hiro

Re:ファイルのコピーが上手くいきません。

#4

投稿記事 by hiro » 18年前

boxさん
keichanさん

回答ありがとうございます。
最小限の変更として下記の2点の修正で上手くいきました。

boxさん指摘のstdlib.hを入れると確かにワーニングが消えました。
ただ、それだけでは解決しなかったので、keichanさん指摘のbを追加しました。
fin = fopen(argv[1],"rb");
fout = fopen(argv[2],"wb");

入力ファイルはテキストエディタで作成した3行ものです。
なぜ、バイナリ―タイプにしたら上手くいったのでしょうか?

hiro

Re:ファイルのコピーが上手くいきません。

#5

投稿記事 by hiro » 18年前

先ほどのメールに、こちらの環境を書くのを忘れていました。
Microsoft Visual C++ 6.0 です。

あと、boxさんの書かれていた、

>argcが3以上であるかどうかを判定してから、

という文の意味がわかりません。
教えて頂ければ幸いです。

box

Re:ファイルのコピーが上手くいきません。

#6

投稿記事 by box » 18年前

>argcが3以上であるかどうかを判定してから、

プログラム名 入力ファイル名 出力ファイル名 <Enter>
という形式で実行しますね。

このとき、コマンドライン引数の個数は
・プログラム名の文字列(へのポインタが、argv[0]に入っている)
・入力ファイル名の文字列(へのポインタが、argv[1]に入っている)
・出力ファイル名の文字列(へのポインタが、argv[2]に入っている)
の3個あります。この「3」が、main関数の引数であるargcの値です。

argcが3以上(ちょうど3でもいいです)というのは、
想定している形式に則って実行している、ということです。

例えば、
プログラム名 入力ファイル名 <Enter>
という形式だと、argcの値は2です。つまり、想定形式どおりではないわけです。

プログラムでargv[1]およびargv[2]に正しくアクセスするためには、
argcが3(以上)でなければなりません。

keichan

Re:ファイルのコピーが上手くいきません。

#7

投稿記事 by keichan » 18年前

>入力ファイルはテキストエディタで作成した3行ものです。
>なぜ、バイナリ―タイプにしたら上手くいったのでしょうか?
考えられる可能性としては標準関数では処理できない"文字コード"で保存されている。というのが挙げられます。
Shift_JISで保存した場合は改行は'\r' + '\n'で表現されますが、その他文字コードだとそれ以外の可能性があります。
その入力ファイルはどのようなテキストエディタで作成されましたか?

hiro

Re:ファイルのコピーが上手くいきません。

#8

投稿記事 by hiro » 18年前

boxさん
keichanさん
ありがとうございます。

argcの数値を出力して3になるのを確認しました。

あと、入力ファイルの出力をunicodeにしていました。
データを作成したメモ帳の出力をANSIにした入力ファイルを使用すると出力ファイルが正常になりました。
(良く見ると画面への出力も変りました。悪い入力データの時にはスペースが入ったように間隔が開いていましたが、良くなった入力データでは詰まって表示されています。)

プログラム以前の所にも問題があったのですね!
本当に、ありがとう御座いました。

閉鎖

“C言語何でも質問掲示板” へ戻る