11

这是我正在编写的程序的基本代码,用于练习使用 C 中的文件。我试图检测输出文件是否已经存在,如果它确实存在,我想询问用户是否愿意覆盖它。这就是我首先使用 fopen(outfilename,"r"); 打开 outfilename 文件的原因。而不是 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);

当你输入第二个字符串并按下 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 readlinencurses 。

于 2011-12-11T14:25:45.257 回答
0

scanf("%s", ...)留下 \n 终止输入中的行。它不会导致下一个问题,因为 scanf("%s", ...) 从跳过白人开始。 scanf("%c", ...)没有,因此您阅读了\n.

顺便说一句,您可能会遇到其他问题,即您在文件名中添加了空格(%s不读取它们)以及输入的名称太长(%s 没有输入长度限制)。

您抱怨的问题的一种解决方案(但不是另一个)是使用scanf(" %c", ...)(参见前面的空格%cscanf很难使用),它首先跳过空格。

于 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 回答