2

我想通过标准输入从用户那里获取文件名,用 open() 打开文件并将其分配给文件描述符,然后将该文件的内容打印到标准输出。这是我的代码,它不能正常工作。

问题:

  1. printf("输入文件名"); 声明从未出现
  2. 它永远不会打开文件;而是将用户输入的任何内容打印到屏幕上,然后打印“没有此类文件或目录”错误消息并退出程序
  3. 程序存在后,我看到在终端提示之前打印“输入文件名”

代码:

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

安慰:

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...? 
4

2 回答 2

2

<stdio.h>输入/输出例程被缓冲(请参阅stdio(3)setbuf(3)。您需要调用fflush(3)(在最近的 libc 上,stdout如果您使用fgetsor阅读,则会隐式调用它scanf)。您确实应该避免混合文件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); };

实际上,如果您保留非常重要的终止符(换行符)fflush,则可以避免这种情况。\n如果你不想要任何换行符,你最好打电话fflush(但有些 libc 正在为你调用它)。

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

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

于 2013-10-31T18:47:41.810 回答
2

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

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

{
    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);
}
于 2013-10-31T18:51:09.510 回答