如何解决从标准输入连续读取
我刚开始学习 C,如果我错过了一些明显的东西,很抱歉。作为一种实践,我想编写自己的 posix cat
并且我几乎让它正常工作,但是当没有参数时,它不会从 stdin 读取多个文件。
这是预期的行为(忽略这一点,因为这是我不知道的 Zsh 功能):
$ cat < hello.txt < world.txt
hello
world
$
但是我的 cat
因“分段错误”而崩溃(我有一个没有崩溃但也没有输出任何内容的版本)
代码如下:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
char opt;
while ((opt = getopt(argc,argv,"u")) != EOF) {
switch(opt) {
case 'u':
/* Make the output un-buffered */
setbuf(stdout,NULL);
break;
default:
break;
}
}
argc -= optind;
argv += optind;
int i = 0,fildes,fs = 0;
do {
/* Check for operands,if none or operand = "-". Read from stdin */
if (argc == 0 || !strcmp(argv[i],"-")) {
fildes = STDIN_FILENO;
} else {
fildes = open(argv[i],O_RDONLY);
}
/* Check for directories */
struct stat fb;
if (!fstat(fildes,&fb) && S_ISDIR(fb.st_mode)) {
fprintf(stderr,"cat: %s: Is a directory\n",argv[i]);
i++;
continue;
}
/* Get file size */
fs = fb.st_size;
/* If bytes are read,write them to stdout */
char buf[fs];
while ((read(fildes,buf,fs)) > 0)
write(STDOUT_FILENO,fs);
/* Close file if it's not stdin */
if (fildes != STDIN_FILENO)
close(fildes);
i++;
} while (argv[i] != NULL || argc == 0);
return 0;
}
解决方法
当您使用 gcc 编译代码时,-fsanitize=address
代码显示:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==604950==ERROR: AddressSanitizer: stack-overflow on address 0x7ffea6d94000 (pc 0x55b9a63dfb57 bp 0x7ffea6d90d20 sp 0x7ffea6d90b80 T0)
#0 0x55b9a63dfb57 in main /tmp/10/1.c:56
#1 0x7f1403c17b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
#2 0x55b9a63df3dd in _start (/tmp/.ccrun.604893.exefile+0x23dd)
SUMMARY: AddressSanitizer: stack-overflow /tmp/10/1.c:56 in main
==604950==ABORTING
第一个片段:
do {
...
++i;
} while (argv[i] != NULL || argc == 0); // HERE!
argc
始终为 0
,因此 while(...)
始终在执行,而 ++i
始终在递增。 argc[...]
被越界访问,直到出现段错误。
我认为您应该将其更改为 } while (argv[i] != NULL && argc != 0);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。