【问题标题】:junk characters from stdin after reading from file in C从 C 中的文件读取后来自标准输入的垃圾字符
【发布时间】:2013-10-10 23:49:48
【问题描述】:

从控制台成功读取重定向文件到我的程序后,我要求用户输入一个单词,然后使用 scanf() 读取该单词。

我遇到的问题是 scanf() 会立即读取垃圾字符,然后程序继续运行。它甚至不会暂停让用户在控制台中输入任何内容。当我不打开文件时,它不会发生。其他一切都完美无缺。可能是什么问题:

**我尝试了所有建议的方法,但仍然无法正常工作。我做了一个新项目,只是为了让这部分工作,就是这样。忽略 scanf 只寻找一个字符,即使我要求一个词。我这样做只是为了看看程序是否真的会暂停并允许我输入一些东西,但事实并非如此。只是进入一些垃圾,程序结束。

 main(){

       int n,i;
       char ch;
       char line[80];

       while(fgets(line, 80, stdin) != NULL){
         for(i=0;i<80;i++){
            ch=line[i];
            if(ch=='\n'){
                printf("%c",ch);
                break;
            }
            else{
                    printf("%c",ch);
            }
         }
       }
       printf("Please enter a word: ");
       scanf("%c",&ch);
    }

【问题讨论】:

  • 请尝试在您的一些标点符号周围添加一些空格。您的代码几乎看起来像解密出错了...... :(

标签: c file-io stdin scanf


【解决方案1】:

您不能从文件重定向标准输入,然后也使用键盘进行输入(据我所知)。如果你想这样做,让程序将输入文件作为命令行参数,然后像这样运行它会更简单:prog myfile.txt。另外,给自己留一个 fgets() 的垫子——使用比分配给 maxlen 的数组少一个。对于需要最大长度的任何内容,如果最大长度不包括 '\0' 终止字符,则使用 C 字符数组比分配的长度小一总是最安全的。

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

int main(int argc,char *argv[])

       {
       FILE *f;
       int i;
       char line[80];

       if (argc<2)
           {
           printf("Usage:  %s <inputfile>\n",argv[0]);
           exit(10);
           }
       /* Open file and echo to stdout */
       f=fopen(argv[1],"r");
       if (f==NULL)
           {
           printf("Cannot open file %s for input.\n",argv[1]);
           exit(20);
           }
       while (fgets(line, 79, f) != NULL)
           printf("%s",line);
       fclose(f);

       /* Get user input from stdin */
       printf("Please enter a word: ");
       if (fgets(line,79,stdin)==NULL)
           {
           printf("Nothing entered.  Program aborted.\n");
           exit(30);
           }
       /* Remove CR/LF from end of line */
       for (i=strlen(line)-1;i>=0 && (line[i]=='\n' || line[i]=='\r');i--)
           ;
       line[i+1]='\0';
       printf("The word entered is: '%s'\n",line);
       return(0);
       }

【讨论】:

  • +1 表示“注意编译器警告”。人们(尤其是初学者)往往会忘记编译器对 C 的了解比他们多得多,如果您提出要求,编译器会帮助您改进您的 C。使用 GCC,您应该定期使用 -Wall 进行编译;我使用-Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition 并希望我的代码在编译时出现零警告(有时通过添加-Werror 来强制执行)。
  • @JonathanLeffler -- 阿门。没有什么比在没有警告的情况下编译大量代码更令人满意的了。
  • 好的。我按照建议更改了它,当我从源代码手动打开文件时它可以工作。但是,当我将代码更改为从标准输入读取,然后从命令行将相同的文件重定向到程序时,它会做和以前一样的事情,并且不会暂停以允许用户输入任何数据,并且正在打印垃圾字符。和以前一样,但现在只有当我从命令行重定向文件并从标准输入读取时
  • @user2845183 -- 您需要检查您的第二个 fscanf 是否有零结果(未找到字符串)。如果您从文件重定向,我建议使用 fgets 从标准输入获取一行。然后检查返回值是否为 NULL。这意味着您位于重定向文件的末尾。否则,对 fgets 读取的字符缓冲区使用 sscanf。
  • 已编辑原始帖子。请帮忙!我这辈子都想不通!
【解决方案2】:

sscanf 用于从流或缓冲区输入,在 unix 中,stdin 被视为文件,因此您应该使用从文件输入的 fscanf,因此请使用 fscanf(stdin,"%s",testword);

【讨论】:

  • 该标准使用术语“流”来指代文件流或FILE *sscanf() 不与文件流一起使用,而是与字符缓冲区一起使用。标准中提到了sscanf()sscanf 函数等效于fscanf,除了输入是从字符串(由参数s 指定)而不是从流中获得的。
猜你喜欢
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-03
相关资源
最近更新 更多