2012-04-11 32 views
0

Cプログラミングの初心者です。私は読書のために開いているファイルの名前を入力するようにユーザーに促すプログラムを書いています。私のコードでは、次のように表示されます。開いていない場合、またはファイルが存在しない場合はエラーが発生しますが、実行するとコードが壊れてプログラムを終了する必要があります(DOS)C - ユーザーにファイル名の入力を促す方法

/*ask user for the name of the file*/ 
    printf("enter file name: "); 
    gets(fname); 


//Opens the file from where the text will be read. 
fp=fopen(fname, "r"); 

//Checks if the file us unable to be opened, then it shows the error message 
if (fp == NULL) 
    { 
    printf("\nError, Unable to open the file for reading\n"); 
    } 

//これをテストするには、name.txtファイルを作成します。追加情報が必要な場合はお知らせください。

+6

'fname'はどのように定義しましたか?ああ、してください、してください、使用しないでください。可能性のある代替手段として 'fgets'を考えてください。 –

+0

あなたが「いつ実行するか」と言ったとき、特にCを初めて使う人には、何を意味するのかも明確にすべきです。それはコンパイルされていない、実行中にすぐにクラッシュする、または試した後にクラッシュするということですか?ファイル名を入力してEnterを押しますか? – merlin2011

答えて

0

あなたが紛失していることはわかりませんが、このプログラムはコマンドラインでcl.exeを使用して私のためにコンパイルして実行します。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(){ 
    char fname[100]; 
    FILE* fp; 
    memset(fname, 0, 100); 
    /*ask user for the name of the file*/ 
    printf("enter file name: "); 
    gets(fname); 


    //Opens the file from where the text will be read. 
    fp = fopen(fname, "r"); 

    //Checks if the file us unable to be opened, then it shows the error message 
    if (fp == NULL) 
    { 
     printf("\nError, Unable to open the file for reading\n"); 
    } 

} 

はまた、(Microsoftのを含む)特定のコンパイラがデフォルトのオプションで呼び出されたときに、関数の先頭にすべての宣言を置くためにあなたを必要とすることに注意してください。

3

さて、あなたはそうしないと、ほぼ確実に破損の原因となります。例えば

:-)、次のスニペットを「爆破」、ファイル名を格納するためのfnameに十分なスペースがあるか確認してください。

char fname[10]; 
gets (fname); 

は、fnameが保持できる情報より多くの情報を入力すると問題になります。その時点で、あなたは未定義の行動領域に入り、何かが起こる可能性があります。

しかし、getsはユーザーの入力を制限する方法がないため、は使用しないでください。

適切で保護されたユーザー入力方法は、this answerにあります。

fgetsは、ユーザーの入力内容を制限できるため、fgetsを使用しています。プロンプトが表示され、何かが間違っている場合にエラーを表示し、ファイルの終わりを正しく処理し、大きすぎる行の残りを削除して次の入力操作に影響を与えないようにします。

実際に、私はこの答えは、自己完結型にするためにここでそれをコピーします:

#include <stdio.h> 
#include <string.h> 

#define OK  0 
#define NO_INPUT 1 
#define TOO_LONG 2 
static int getLine (char *prmpt, char *buff, size_t sz) { 
    int ch, extra; 

    // Get line with buffer overrun protection. 
    if (prmpt != NULL) { 
     printf ("%s", prmpt); 
     fflush (stdout); 
    } 
    if (fgets (buff, sz, stdin) == NULL) 
     return NO_INPUT; 

    // If it was too long, there'll be no newline. In that case, we flush 
    // to end of line so that excess doesn't affect the next call. 
    if (buff[strlen(buff)-1] != '\n') { 
     extra = 0; 
     while (((ch = getchar()) != '\n') && (ch != EOF)) 
      extra = 1; 
     return (extra == 1) ? TOO_LONG : OK; 
    } 

    // Otherwise remove newline and give string back to caller. 
    buff[strlen(buff)-1] = '\0'; 
    return OK; 
} 

あなたは次のようにバッファとサイズを指定して、それを呼び出し、戻り値にエラー表示を受信することができます

うまく
// Test program for getLine(). 

int main (void) { 
    int rc; 
    char buff[10]; 

    rc = getLine ("Enter string> ", buff, sizeof(buff)); 
    if (rc == NO_INPUT) { 
     // Extra NL since my system doesn't output that on EOF. 
     printf ("\nNo input\n"); 
     return 1; 
    } 

    if (rc == TOO_LONG) { 
     printf ("Input too long [%s]\n", buff); 
     return 1; 
    } 

    printf ("OK [%s]\n", buff); 

    return 0; 
} 
+0

scanfを使うだけですか? – NewLearner

+0

@NewLearnerの場合、特に '無制限の文字列'形式の文字列 '%s'を使用すると、' scanf'に他の問題があります。それもバッファオーバーフローの対象となります。 'scanf'は" scan formatted "を意味し、ユーザーの入力よりも_unformatted_はそれほど多くはありません:-)間違ってはいけません。ほとんどの場合、特にCやクラスワーク、あるいはすばやく汚いプログラムの場合は問題ありません。それは生産品質のコードには良いことではありません。 – paxdiablo

0

、これがme.Belowのために働いていたが、コードで言及した「場合」の「他」の条件を追加して、私と一緒に何が起こったかです。

#include<stdio.h> 
#include<conio.h> 
#include<string.h> 

int main() 
{ 

char fname[100]; 
FILE* fp; 
memset(fname, 0, 100); 
/*ask user for the name of the file*/ 
printf("enter file name: "); 
gets(fname); 

fp = fopen(fname, "r"); 

//Checks if the file us unable to be opened, then it shows the error message 
if (fp == NULL) 
{ 
    printf("\nError, Unable to open the file for reading\n"); 
} 

else 
{ 
    printf("hello"); 
} 


getch(); 
} 

また、ヘッダーファイルに「#include」が追加されていることを確認してください。

関連する問題