C低级标准输入接受文件名然后将文件内容打印到标准输出

我想通过stdin从用户获取文件名,用open()打开文件并将其分配给文件描述符,然后将该文件的内容打印到stdout。 这是我的代码,但它无法正常工作。

问题:

  1. printf(“输入文件名”); 声明永远不会出现
  2. 它从不打开文件; 相反,无论用户输入打印到屏幕上,然后打印“无此文件或目录”错误消息并退出程序
  3. 程序存在后,我看到在终端提示符前打印的“输入文件名”

码:

{ printf("Enter the filename: "); read(STDIN_FILENO, userInput, sizeof(userInput)); if((input_file1 = open(userInput, O_RDONLY))  0) { if((write(STDOUT_FILENO, buffer, n)) < 0) { perror("failed to write to standard-out"); close(input_file1); exit(1); } } } 

安慰:

 machine{user1}168: ls // to show that the file exists a.out backup file1 machine{user1}170: ./a.out file1 // this is user input file1 // this is printed for no reason : No such file or directory // ???? Enter the filename: machine{user1}171: // now the prompt is printed...? 

缓冲输入/输出例程(参见stdio(3) & setbuf(3) 。你需要调用fflush(3) (在最近的libc上,如果你用fgetsscanf读取它会被隐式调用stdout )你真的应该避免在相同的输出或输入上混合文件描述符和FILE句柄(参见fileno(3)但总是调用fflush ….)。所以替换

  printf("Enter the filename: "); read(STDIN_FILENO, userInput, sizeof(userInput)); 

  printf("Enter the filename: \n"); fflush(NULL); if (!fgets(userInput,sizeof(userInput),stdin)) { perror("fgets"); exit(EXIT_FAILURE); }; 

实际上,如果你保持非常重要的终止\n (换行符),可以避免fflush 。 如果你不想要任何新行,你最好调用fflush (但有些libc正在为你调用它)。

过度或过于频繁地调用fflush危害要小得多(因为在所有已经刷新的流上它是无操作的)比调用它太少或不够。

但是你应该学习getline(3) (以避免固定长度的线条)。 在Linux和GNU系统上, readline值得使用:它使您能够提供性感的提示,并且您的用户可以编辑键入的行。

您的提示永远不会出现,因为您使用read()而不是标准I / O函数之一( scanf()fgets()等)来获取输入。 在调用read()之前更改输入函数或使用fflush(stdout)fflush(0) read()

您的读取包括换行符,因此打开尝试使用名称末尾的换行符打开文件。 该文件不存在,因此打开失败。

 { printf("Enter the filename: "); if (fgets(userInput, sizeof(userInput), stdin) == 0) { fprintf(stderr, "Oops!\n"); exit(1); } userInput[strlen(userInput)-1] = '\0'; if ((input_file1 = open(userInput, O_RDONLY)) < 0) { perror(userInput); exit(1); } while ((n = read(input_file1, buffer, sizeof(buffer))) > 0) { if (printf("%.*s", n, buffer)) != n) { perror("failed to write to standard-out"); close(input_file1); exit(1); } } close(input_file1); }