まず、コードのレイアウトが非常にわかりにくく、このままではコンパイルできません。呼び出すことがないように見える関数input()
があり、別の関数内にあるはずのコードを関数の外に残しているか、さらに良いmain()
ことに、実行できるようにすべてのコードを関数内に含める必要があります。これは、やりたいことのクリーンアップされた例です。
#include <stdio.h>
char in[80],out[80];
int main()
{
printf("Client: ");
scanf("%[^\n]",in); //you really should use fgets() here
FILE* fp = fopen("test.txt","w");
if (!fp)
{
perror("Failed to open file");
return 1;
}
fputs(in,fp);
fputs("\n",fp);
fclose(fp);
fp = fopen("test.txt","r");
if (!fp)
{
perror("Failed to open file");
return 1;
}
fgets(out,80,fp);
fclose(fp);
fp = fopen("test.txt","a+");
if (!fp)
{
perror("Failed to open file");
return 1;
}
if (strcmp ("Knock Knock\n",out)==0)
fputs("Server: Who is there?\n",fp);
return 0;
}
いくつかの重要な注意事項:
1)の戻り値であるためfp
、 file-type がありますが、そのように宣言することはありません。したがって、これはそのエラーでコンパイルされることはありません。FILE*
fopen()
2) フラグ付きのファイルを開くたびw
に、ファイルの内容全体が消去されます。したがって、プログラムからの出力の履歴を保持するためにファイルに追加するつもりだった場合は、a+
呼び出すときにフラグを使用する必要があります。fopen()
3) プログラムが から入力を取得した後に「test.txt」が空である理由に頭を悩ませるのではなく、ファイルを開くことができなかった場合に何らかのエラーを出力できると便利ですstdin
。また、ファイルを再度開く場合は、毎回 NULL を確認してください。これは、NULL ファイル ポインターを操作しようとすると予期しない結果が生じるためです (ほとんどの場合、クラッシュします)。
4)scanf()
ユーザー入力(または悪意のあるユーザー入力)から厄介なバッファオーバーランが発生する可能性があります...代わりに既知の長さのバッファを使用fgets()
します。stdin
これで、このコードをコンパイルして実行できるはずです。Ubuntuのgcc 4.4.3で動作します。実行後、「test.txt」ファイルは次のようになります。
Knock Knock
Server: Who is there?