【发布时间】:2018-02-10 21:39:27
【问题描述】:
我想制作一个非常简单的控制台应用程序来替换 Unix 命令wc -c。为此,我只需要简单地计算文件中的字节数并在控制台中输出它们。
如果我的应用程序没有提供参数,它会从标准输入中读取它们(这部分我已经开始工作了)。但是,如果我决定提供更多参数(有效的和现有的文件名),我应该计算每个参数的字节数。
到目前为止一切顺利。这是代码
const int __OPEN_ERROR = 48;
int main(int argc, char* argv[]) {
if(argc == 1) {
char buf[3];
int count = 0, lines = 0;
while(read(0, buf, 1) != 0) {
count++;
if(buf[0] == '\n')
lines++;
}
printf("Count:%d\n", count);
printf("Lines:%d\n", lines);
}
else {
int fd, bytes = 0;
char buf[3];
for (int arg = 1; arg <= argc; arg++) {
if ((fd = open(argv[arg], O_RDONLY) < 0)) {
exit(__OPEN_ERROR);
}
while (read(fd, buf, 1) != 0) { // <-- this here leads to infinite loop.
printf("%s", buf);
bytes++;
}
printf("%d %s", bytes, argv[arg]);
}
}
exit(0);
}
请不要介意这段代码写得有多糟糕,这是我探索 C 的第一天,现在我想要的一切都是可行的解决方案。
请注意两个读取是如何相同的,但后一个会陷入无限循环,原因我无法理解。是的,打开文件成功了。
【问题讨论】:
-
argv[argc]将始终为空指针。然而你试图用它来打开一个文件。 -
arg <= argc应该是arg < argc -
printf("%s", buf)导致未定义的行为,因为buf中没有空终止符。 -
Tangential:请注意,通常不应创建以下划线开头的函数或变量名称。 C11 §7.1.3 Reserved identifiers 说: — 所有以下划线开头的标识符以及大写字母或另一个下划线始终保留用于任何用途。 — 所有以下划线开头的标识符始终保留用于在普通名称空间和标记名称空间中用作具有文件范围的标识符。 另请参阅What does double underscore (
__const) mean in C?
标签: c unix file-descriptor