我无法使用fgets从文件中读取几行文本。该文件是一些基本用户数据,在第一次启动插件时写入包中的文件。随后启动插件应导致读取和交叉引用用户数据以检查用户的真实性。
数据总是长3行,用frwite完全按原样写入,并用fopen打开。
我最初的理论是只调用fgets 3次将每行读入它自己的char数组,这是数据结构的一部分。问题是第一行被正确读取,第二行被读取,好像位置指示符在下一行开始但被第1行读取的字符数偏移。然后根本不读取第三行。
fgets没有返回任何错误,并且表现得好像已经读取了应该拥有的数据,所以我显然错过了一些东西。
无论如何,这里是我的代码的一部分,希望有人可以解决我的错误!
int length;
fgets(var.n, 128, regFile);
length = strlen(var.n);
var.n[length-1] = NULL;
fgets(var.em, 128, regFile);
length = strlen(var.em);
var.em[length-1] = NULL;
fgets(var.k, 128, regFile);
length = strlen(var.k);
var.k[length-1] = NULL;
fclose(regFile);
将每个字符串中的最后一个字符设置为NULL只是为了删除/ n
这段代码输出整行第1行,第2行的后半部分而不是第3行。
答案 0 :(得分:1)
感谢@alvits对此问题的回答:
fwrite()与fgets()不兼容。使用fwrite()创建的文件应该使用fread()来读取它们吗?>回来。除非明确地转换为>字符串,否则fwrite()和fread()都对二进制流进行操作。 fgets()与fputs()兼容,两者都在字符串上运行。
我使用fputs()来编写我的数据,然后完全回读。
答案 1 :(得分:0)
在POSIX系统(包括Linux)中,二进制文件和文本文件之间没有区别。打开文件流时,将忽略b
标志。这在fopen()
。
您可能会问"您如何区分文本和二进制文件?"。内容区分了它们。如何写入内容使它们成为二进制文件或文本文件。
查看签名size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
。您会注意到它会写*ptr
的内容,其中size
描述每个成员的大小nmemb
。写入的流不会转换为字符串。如果您要编写97,它将写入ascii为A
的二进制97。二进制数据不遵循字符串终止。数据中\n
和\0
的存在按字面编写。
现在看一下签名int fputs(const char *s, FILE *stream)
。它写入*s
的字符串内容。如果你要写97,它必须是一个字符串" 97"这不是A
。遵循字符串终止。 \n
会自动转换为支持O / S的换行符(CRLF或LF)。
你可以强迫fwrite()
表现得像fputs()
,但不能反过来。例如,如果将ptr
声明为指向字符串的指针并将其大小精确地计算为除字符串终止符之外的内容长度,则您可以将其写为文本而不是二进制文件。您还需要处理\0
和\n
并将其转换为O / S支持的换行符。编写整个字符串缓冲区将写入包括字符串终止符在内的所有内容。