如何解决C、调用 fread 时消除循环?
我用 C 写了这段代码:
char tmp[strlen(argv[1]) + 1];
for (int j = 0; j < strlen(argv[1]) + 1; ++j) {
fread(&tmp[j],1,file);
}
我更喜欢消除 for 循环以使代码更短,所以它等于这个(选项 A):
char tmp[strlen(argv[1]) + 1];
fread(&tmp,strlen(argv[1]) + 1,file);
还有这个(选项 B):
char tmp[strlen(argv[1]) + 1];
fread(&tmp,file);
从我在 fread
上读到的内容来看,两者的答案都是肯定的,但想了解 A 或 B 哪个更可取?
解决方法
在我看来,没有一个选项是可取的,如果不知道您想要实现什么,就没有答案。
从语法来看,您的代码可以编译并且是正确的。从逻辑的角度来看它是不可用的。
您不知道在您的代码中实际读取了多少数据,因此您无法使用存储在 tmp 中的数据。如果您的文件内容大于数组,或者文件不包含空终止符(如果它是文本文件,则很可能不包含空终止符),则您无法指示有多少字符被读入数组。
至少您应该存储 fread
的返回值以了解实际读取了多少数据以及您的数组中有多少数据是有效的。另一种方法是用零字节(通过 = {};
或 memset
)完全初始化您的数组,以确保在有效数据后找到空终止符或您的数组完全满,因此您可以在以下情况下终止从数组中读取。
记住一些事情:
- 循环不是邪恶的,也不是杂乱的代码,也不会减慢执行速度,因此您可以在阅读用户输入(恕我直言)时证明不使用它们是合理的
- 您正在处理用户输入,因此预计会有意外的数据和意外的大小。您的代码应该处理这些问题,以便编写健壮且容错的代码。
- 可能会发生读取错误。因此,如果您想阅读完整文件,请为此做好准备。例如,如果您的程序被信号中断(至少在 linux 上),则读取将终止。因此,您可能需要多次尝试阅读整个文件。信号会发生,您不能保证它们不会发生。例如。如果你 fork 另一个进程并且另一个进程死了,它会触发
SIGCHILD
。举个例子。 - 您使用
strlen
的argv[1]
作为数组长度。这不会告诉您file
的内容是否适合它。所以你应该澄清你的问题,你的程序实际上应该做什么。此外,如果您认为file
根据长度或tmp
适合argv[1]
,它仍然是您阅读的文件,其中可能包含意外内容。
简答:没有一个选项是正确的(但也许选项 B 有意义)
说明: 您必须查看的第一件事是 fread 文档以了解每个参数的用途: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fread?view=msvc-160
所以第二个参数是以字节为单位的项目大小,第三个参数是要读取的最大项目数。
这意味着在第二个参数中,您应该传递要读取的文件变量内容的总长度。 (如果 strlen(argv[1])+1 包含该长度,您的代码可能有意义,但这样做不是一个好习惯)。
建议:不要试图让您的代码只有几行会影响错误控制、可读性或其他问题,并且不要认为用户 (argv) 会很好地使用您的程序。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。