[英]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: 问题:
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上,如果使用fgets
或scanf
读取,则隐式调用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.