11

これは、C でファイルを使用して練習するために書いているプログラムの基本的なコードです。出力ファイルが既に存在するかどうかを検出しようとしています。存在する場合は、ユーザーに上書きするかどうかを尋ねたいと思います。これが、最初に outfilename ファイルを fopen(outfilename,"r"); で開いた理由です。fopen(outfilename,"w"); とは対照的です。

ファイルが存在しない場合を検出しますが、存在する場合は printf("Output file already exists, overwrite (y/n):"); を実行します。ステートメントですが、scanf("%c",&yn); を完全に無視します。声明!

プログラムの最後のprintfは、ファイルが存在しない場合は「yn = 0」を読み取り、存在する場合は単に「yn =」を読み取ります。誰でも私を助けることができますか?

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

int main(void) {
    FILE *inf;
    FILE *outf;
    char filename[21],outfilename[21];
    char yn='0';

    printf("Please enter an input filename: ");
    scanf("%s",&filename);

    printf("Please enter an output filename: ");    
    scanf("%s",&outfilename);

    /* Open file for reading */
    inf=fopen (filename,"r");
    outf=fopen(outfilename,"r");

    /*check that input file exists*/
    if (inf!=NULL) {

        /*check that the output file doesn't already exist*/
        if (outf==NULL){
            fclose(outf);
            /*if it doesn't already exist create file by opening in "write" mode*/
            outf=fopen(outfilename,"w");
        } else {
            /*If the file does exist, give the option to overwrite or not*/
            printf("Output file already exists, overwrite (y/n):");
            scanf("%c",&yn);
        }
    }
    printf("\n yn=%c \n",yn);
    return 0;
}
4

5 に答える 5

41
printf("Please enter an output filename: ");    
scanf("%s",&outfilename);

2 番目の文字列を入力して ENTER キーを押すと、文字列と文字が入力バッファーに配置されます。つまり、入力された文字列と改行文字です。文字列は によって消費されscanfますが、改行は入力バッファーに残ります。 .

さらに遠く、

scanf("%c",&yn);

scanfの文字の読み取りは、改行を読み取り/消費するため、ユーザー入力を待つことはありません。

解決策は、次を使用して余分な改行を消費することです。

scanf(" %c", &yn);
      ^^^   <------------Note the space

または使用してgetchar()

問題の詳細なステップバイステップの説明については、ここで私の回答を確認してください。

于 2011-12-11T14:22:27.700 に答える
1

使用する

scanf("%20s",&filename);

stdinは行バッファリングされており、Linux ではtty規律に従っていることを思い出してください。

より詳細な制御が必要な場合は、GNU readlineまたはncursesを使用できます。

于 2011-12-11T14:25:45.257 に答える
0

scanf("%s", ...)\n入力の行を終了します。scanf( "%s"、...)は白をスキップすることから始まるため、次の問題は発生しません。 scanf("%c", ...)そうではないので、あなたはを読みます\n

ところで、おそらく他の問題に遭遇するでしょう。ファイル名にスペースを入れて(%sそれらを読み取らない)、長すぎる名前を入力した場合(%sには入力長の制限がありません)。

あなたが不満を言った問題の1つの解決策(他の解決策ではない)は、空白をスキップすることから始める(使用するのが難しいscanf(" %c", ...)前のスペースを参照)を使用すること%cです。scanf

于 2011-12-11T14:28:32.120 に答える
0
scanf("%s",&filename);

& も削除します

scanf.c:13: 警告: フォーマット '%s' はタイプ 'char ' を想定していますが、引数 2 のタイプは 'char ( )[20u]' です

于 2011-12-11T14:32:38.310 に答える
0

私が見つけたこの問題を処理するより良い方法は、ここで説明されています

ハンドル入力の別の方法を使用することをお勧めし、非常によく説明されています。

私は常にこの関数を使用して、ユーザー入力を取得します。


char * read_line (char * buf, size_t length) {
    /**** Copyright de home.datacomm.ch/t_wolf/tw/c/getting_input.html#skip
    Read at most 'length'-1 characters from the file 'f' into
    'buf' and zero-terminate this character sequence. If the
    line contains more characters, discard the rest.
    */
    char *p;
    if ((p = fgets (buf, length, stdin))) {
        size_t last = strlen (buf) - 1;
        if (buf[last] == '\n') {
            /**** Discard the trailing newline */
            buf[last] = '\0';
        } else {
            /**** There's no newline in the buffer, therefore there must be
            more characters on that line: discard them!
            */
            fscanf (stdin, "%*[^\n]");
            /**** And also discard the newline... */
            (void) fgetc (stdin);
        } /* end if */
    } /* end if */
    return p;
} /* end read_line */

古い回答

このルールでこの種の問題を修正しました。

// first I get what I want.
c = getchar();
// but after any user input I clear the input buffer
// until the \n character:
while (getchar() != '\n');
// this also discard any extra (unexpected) character.

任意の入力後にこれを作成すれば問題ないはずです。

于 2012-04-13T00:12:20.177 に答える