我应该如何考虑 fread() 的参数?
How should I think about the parameters of fread()?
很容易找到 C 风格的流行约定 I/O。更困难的是找到关于为什么他们是这样的解释。常见的阅读语句如下:
fread(buffer, sizeof(buffer), 1, ptr);
程序员应该如何考虑使用fread()的参数size和n?
例如,如果我的输入文件是100字节,我应该选择更大的尺寸和更少的n还是读取更小尺寸的更多对象?
如果size-to-be-read和n超过输入文件的字节大小,会发生什么?通俗地说,读取的多余字节是否由 "junk values"?
组成
首先,while (!feof(ptr))
是 错误的 并且是一个非常糟糕的反模式。在某些情况下它可以工作,但它几乎总是比正确的惯用用法更复杂。 fread
或其他 stdio 读取函数的 return 值 已经告诉你它是否没有成功 ,你通常需要能够立即处理而不是而不是等待下一个循环迭代开始。如果您正在学习的任何资源正在教授这个 while (!feof(ptr))
东西,您可能应该停止将其作为学习 C 的来源。
现在,关于您关于 size
和 n
参数的具体问题:将它们分开是完全没有必要的,也没有用。只需传递所需的长度以读取其中一个,并为另一个传递 1
。如果您希望能够确定在遇到文件末尾或错误时已经读取了多少字节,则需要将 1
传递给 size
并将请求的字节数传递为 n
。否则,如果任何比预期短的读取都是错误的,有时切换它们是有意义的;那么唯一可能的 return 值是 1 和 0(分别为成功和错误)。
为了理解为什么,您如何使用这两个参数并不重要,指定了所有 stdio 读取函数,包括 fread
就好像它们是通过重复调用 fgetc
发生的一样。您是否有 size*n
个这样的电话或 n*size
个这样的电话并不重要,因为数字的乘法通勤。
size_t fread(void * restrict ptr, size_t size, size_t n, FILE * restrict stream);
How should a programmer think about using the parameters size and n of fread()?
读入数组时:
size
是被调用指针的取消引用类型的大小。
n
中的元素个数。
some_type destination[max_number_of_elements];
size_t num_read = fread(destination, sizeof *destination, max_number_of_elements, inf);
printf("Number of elements read %zu\n", num_read);
if (num_read == 0) {
if (feof(inf)) puts("Nothing read as at end-of-file");
else if (ferror(inf)) puts("Input error occurred");
else {
// since sizeof *destination and max_number_of_elements cannot be 0 here
// something strange has occurred (UB somewhere prior?)
}
For example, if my input file is 100 bytes, should I opt for a larger size with fewer n or read more objects of a smaller size?
案例中,数据大小为1,最大计数100。
#define MAX_FILE_SIZE 100
uint8_t destination[MAX_FILE_SIZE];
size_t num_read = fread(destination, sizeof *destination, MAX_FILE_SIZE, inf);
If the size-to-be-read and n exceed the byte-size of an input file, what happens?
目的地未填写。使用return值来判断。
Are the excess bytes that were read composed, colloquially speaking, of "junk values"?
没有。 fread()
之前的值保持不变(只要 return 不是 0 且 ferror()
未设置)。如果目的地不是 initialized/assigned,那么是的,它可能是垃圾。
单独的 size, n
允许 fread()
正常运行,即使 size * n
溢出 size_t
数学。对于当前的平面内存模型,很少需要这样做。
很容易找到 C 风格的流行约定 I/O。更困难的是找到关于为什么他们是这样的解释。常见的阅读语句如下:
fread(buffer, sizeof(buffer), 1, ptr);
程序员应该如何考虑使用fread()的参数size和n?
例如,如果我的输入文件是100字节,我应该选择更大的尺寸和更少的n还是读取更小尺寸的更多对象?
如果size-to-be-read和n超过输入文件的字节大小,会发生什么?通俗地说,读取的多余字节是否由 "junk values"?
组成
首先,while (!feof(ptr))
是 错误的 并且是一个非常糟糕的反模式。在某些情况下它可以工作,但它几乎总是比正确的惯用用法更复杂。 fread
或其他 stdio 读取函数的 return 值 已经告诉你它是否没有成功 ,你通常需要能够立即处理而不是而不是等待下一个循环迭代开始。如果您正在学习的任何资源正在教授这个 while (!feof(ptr))
东西,您可能应该停止将其作为学习 C 的来源。
现在,关于您关于 size
和 n
参数的具体问题:将它们分开是完全没有必要的,也没有用。只需传递所需的长度以读取其中一个,并为另一个传递 1
。如果您希望能够确定在遇到文件末尾或错误时已经读取了多少字节,则需要将 1
传递给 size
并将请求的字节数传递为 n
。否则,如果任何比预期短的读取都是错误的,有时切换它们是有意义的;那么唯一可能的 return 值是 1 和 0(分别为成功和错误)。
为了理解为什么,您如何使用这两个参数并不重要,指定了所有 stdio 读取函数,包括 fread
就好像它们是通过重复调用 fgetc
发生的一样。您是否有 size*n
个这样的电话或 n*size
个这样的电话并不重要,因为数字的乘法通勤。
size_t fread(void * restrict ptr, size_t size, size_t n, FILE * restrict stream);
How should a programmer think about using the parameters size and n of fread()?
读入数组时:
size
是被调用指针的取消引用类型的大小。
n
中的元素个数。
some_type destination[max_number_of_elements];
size_t num_read = fread(destination, sizeof *destination, max_number_of_elements, inf);
printf("Number of elements read %zu\n", num_read);
if (num_read == 0) {
if (feof(inf)) puts("Nothing read as at end-of-file");
else if (ferror(inf)) puts("Input error occurred");
else {
// since sizeof *destination and max_number_of_elements cannot be 0 here
// something strange has occurred (UB somewhere prior?)
}
For example, if my input file is 100 bytes, should I opt for a larger size with fewer n or read more objects of a smaller size?
案例中,数据大小为1,最大计数100。
#define MAX_FILE_SIZE 100
uint8_t destination[MAX_FILE_SIZE];
size_t num_read = fread(destination, sizeof *destination, MAX_FILE_SIZE, inf);
If the size-to-be-read and n exceed the byte-size of an input file, what happens?
目的地未填写。使用return值来判断。
Are the excess bytes that were read composed, colloquially speaking, of "junk values"?
没有。 fread()
之前的值保持不变(只要 return 不是 0 且 ferror()
未设置)。如果目的地不是 initialized/assigned,那么是的,它可能是垃圾。
单独的 size, n
允许 fread()
正常运行,即使 size * n
溢出 size_t
数学。对于当前的平面内存模型,很少需要这样做。