简体   繁体   English

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

[英]C low-level standard-in to accept filename then printing file contents to stdout

I want to get a file name from a user via stdin, open the file with open() and assign it to a file descriptor, then print the contents of that file to stdout. 我想通过stdin从用户那里获得一个文件名,使用open()打开文件并将其分配给文件描述符,然后将该文件的内容打印到stdout。 This is my code, and it's not working properly. 这是我的代码,无法正常工作。

Problems: 问题:

  1. the printf("enter filename"); printf(“输入文件名”); statement is never showing up 声明永远不会出现
  2. it never opens the file; 它从不打开文件; instead whatever the user inputs is printed to the screen and then the "no such file or directory" error message is printed and the program exits 而是将用户输入的所有内容打印到屏幕上,然后打印“无此文件或目录”错误消息,并退出程序
  3. after the program exists i see "enter filename" printed before the prompt in terminal 程序存在后,我在终端提示前看到“输入文件名”

CODE: 码:

    {
        printf("Enter the filename: ");
        read(STDIN_FILENO, userInput, sizeof(userInput));
        if((input_file1 = open(userInput, O_RDONLY)) < 0)
        {
            perror(userInput);
            exit(1);
        }

        while((n = read(input_file1, buffer, sizeof(buffer))) > 0)
        {
            if((write(STDOUT_FILENO, buffer, n)) < 0)
            {
                perror("failed to write to standard-out");
                close(input_file1);
                exit(1);
            }
        }
    }

Console: 安慰:

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.h> input/output routines are buffered (see stdio(3) & setbuf(3) . You need to call fflush(3) (on recent libc, it is implicitly called for stdout if you read with fgets or scanf ). And you really should avoid mixing file descriptors and FILE handles on the same output or input (see fileno(3) but always call fflush ....). So replace <stdio.h>输入/输出例程被缓冲 (请参阅stdio(3)setbuf(3) 。您需要调用fflush(3) (在最近的libc上,如果使用fgetsscanf读取,则隐式调用stdout )) 。并且,您实际上应该避免在同一输出或输入上混合使用文件描述符和FILE句柄(请参阅fileno(3),但始终调用fflush ....)。

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

with

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

Actually here the fflush could be avoided if you keep the very important terminating \\n (newline). 其实这里的fflush如果保持非常重要的终端可避免\\n (新行)。 If you don't want any newline you should better call fflush (but some libc are calling it for you). 如果您不希望使用任何换行符,则最好调用fflush (但是某些libc正在为您调用它)。

Calling fflush too much or too often is much less harmful (because on all already flushed stream it is a no-op) than calling it too little or not enough. 过多或过多地调用fflush危害要小得多或不足,因此危害较小(因为在所有已冲洗的流中,这是无操作的)。

But you should learn about getline(3) (to avoid fixed-length lines). 但是您应该了解getline(3) (避免使用固定长度的行)。 On Linux and GNU systems readline is worth using: it enables you to give a sexy prompt, and your user to edit the typed line. 在Linux和GNU系统上, readline值得使用:它使您能够发出性感的提示,而用户可以编辑键入的行。

Your prompt never appears because you use read() instead of one of the Standard I/O functions ( scanf() , fgets() , etc) to get the input. 因为您使用read()而不是标准I / O函数之一( scanf()fgets()等)来获取输入,所以提示永远不会出现。 Either change the input function or use fflush(stdout) or fflush(0) before calling read() . 更改输入函数,或者在调用read()之前使用fflush(stdout)fflush(0) read()

Your read includes the newline, so the open tries to open the file with a newline at the end of the name. 您所读的内容包含换行符,因此打开操作会尝试以名称末尾的换行符打开文件。 That file doesn't exist, so the open fails. 该文件不存在,因此打开失败。

{
    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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM