我想创建一个非常简单的控制台应用程序来取代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,现在我想要的只是工作解决方案。
注意两个读取是如何相同但后一个读入无限循环,这是我无法理解的原因。是的,打开文件成功。
答案 0 :(得分:1)
你的循环错了,应该是:
char buf;
...
while (read(fd, buf, 1) == 1) {
printf("%c", buf);
bytes++;
}
read
允许您从文件描述符中读取字节。给定的数字表示n
是一个请求,这意味着read
最多读取n
个字节,返回的值恰好是有效读取的字节数。如果你想读取1个字节,那么测试它是否读取1个字节。其次,当您逐个读取字节(或字符)时,结果是一个字符,应该打印为。 %c
告诉printf将值打印为char(%s
是打印C字符串)。
另一个错误是控制arg循环,应该是:
for (int arg = 1; arg < argc; arg++) // strict test...arg from 0 to argc-1 (included) or argc (excluded)
您还必须在每次arg循环时将字节数重置为0,并关闭每个未使用的文件,因此:
for (int arg = 1; arg < argc; arg++) {
char buf;
int bytes = 0;
int fd;
if ((fd = open(argv[arg], O_RDONLY) < 0)) {
exit(__OPEN_ERROR);
}
while (read(fd, buf, 1) == 1) {
printf("%c", buf); // optionnal, counting may not print...
bytes++;
}
close(fd);
printf("%d %s", bytes, argv[arg]);
}