c - 需要帮助弄清楚 fgets 的问题是什么
问题描述
所以基本上我有一个文件指针,指向一个在 0 和 1 之间有 80 位数字的文件,我需要将它们放入一个字符串中,然后对其进行处理。
该函数返回NULL
,我找不到问题所在,因为如果它返回NULL
它就意味着错误。
FILE *fpr = fopen(path, "r");
FILE *fpw = fopen("code.txt", "w");
char *str = calloc(81, sizeof(char));
if (fpr == NULL || fpw == NULL) {
printf("yikes");
}
if (fgets(str, 80, fpr) != NULL) { //HERE ITS NULL
int p1 = 0;
int p2 = 0;
我真的想透了,我要么真的很笨,要么没有明显的问题。
解决方案
代码片段中存在一些问题:
- 如果任何文件无法打开,您仍然调用,如果是
fgets()
,它具有未定义的行为。对每个 进行单独测试,打印更明确的错误消息并退出程序。fpr
NULL
FILE*
- 您应该将数组的大小传递给
fgets()
,81
而不是80
. - 该数组应分配到至少 82 个字节:80 个字符加上尾随换行符和一个空字节终止符。
- 您不测试内存分配失败。您甚至不应该分配内存,对于像 82 字节这样的小尺寸,本地数组是可以的。
这是一个更正的版本:
#include <errno.h>
#include <stdio.h>
...
char str[82];
FILE *fpr = fopen(path, "r");
if (fpr == NULL) {
fprintf(stderr, "cannot open input file %s: %s\n", path, strerror(errno));
exit(1);
}
FILE *fpw = fopen("code.txt", "w");
if (fpw == NULL) {
fprintf(stderr, "cannot open output file %s: %s\n", "code.txt", strerror(errno));
exit(1);
}
if (fgets(str, sizeof str, fpr)) {
int p1 = 0;
int p2 = 0;
...
始终测试错误条件并打印明确的错误消息,您将保护自己无数小时的调试时间。
推荐阅读
- php - 如何从 laravel 中的数据透视表中制作可靠的下拉菜单
- r - 在 dplyr 1.0 中重命名 tidyeval 中的列
- c# - Wpf .Net.5 应用程序中的 Prism 和 Uno 平台。使用什么 Nuget 包?
- java - 如何将存储在字符串数组中的特定字符串打印到字符串数组的 ArrayList 中?
- php - Symfony 中的路径类型:何时使用“AppBundle:SomeEntity”或“AppBundle/Entity/SomeEntity”?
- eclipse - 如何诱使 Eclipse 显示缺少的 @Nullable/@NonNull “注释”命令?
- chronicle - 如何将 SelfDescribeingMarshallables 列表序列化为 CSV
- vb.net - 运行带有参数的 .exe,但还要检查它是否存在于 Visual Basic 上
- laravel - 与laravel中的一个json列属于关系
- javascript - 如何在nodejs中分割数组对象?