我基本上做的是以二进制模式打开文件,将其转储到缓冲区并处理它,我终于意识到以二进制模式打开文件导致问题,我在谷歌搜索了一下但是我不知道如何解决它。
代码的目的是减少行数。注意:程序的逻辑是正确的。
#include <stdio.h>
#include <stdlib.h>
int foo(const char *filename);
int main(void)
{
foo("file.txt");
fputs("Press any key to continue...", stderr);
getchar();
return 0;
}
int foo(const char *filename)
{
/* open file in binary mode */
FILE *fp = fopen(filename, "rb");
if (!fp) {
perror(filename);
return -1;
}
/* store file size and allocate memory accordingly */
long f_size;
fseek(fp, 0L, SEEK_END);
f_size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
char *buf = (char *)malloc(f_size+1);
if (!buf) {
puts("Error - malloc failed.");
return -2;
}
/* store file contents in buffer */
size_t bytes_read = fread(buf, 1, f_size, fp);
if (bytes_read != f_size) {
fclose(fp);
free(buf);
puts("read error...");
return -3;
}
else {
fclose(fp);
buf[f_size] = '\0';
}
bool f = 0;
size_t n = 0;
size_t m = 0;
while (buf[n]) {
if (buf[n] == '\n') {
if (f) {
f = 0;
buf[m++] = '\n';
}
}
else {
f = 1;
buf[m++] = buf[n];
}
n++;
}
/* NUL-terminate buffer at m*/
buf[m] = '\0';
/* open file for writing */
fp = fopen(filename, "wb");
if (!fp) {
perror(filename);
free(buf);
return -4;
}
/* write buffer to file */
size_t bytes_written = fwrite(buf, 1, m, fp);
if (bytes_written != m) {
puts("fwrite error...");
}
fclose(fp);
free(buf);
return 0;
}
file.txt的:
00000000
00000000
00000000
期望的输出:
00000000
00000000
00000000
答案 0 :(得分:3)
如果您正在将文本文件处理为文本,则应以文本模式而不是二进制模式打开它。文本文件和二进制文件之间的物理区别是依赖于系统的,并且在某些系统上没有区别,但是可移植程序需要意识到它至少可能会产生影响。这是关于文件内容的C视图,而不是用于访问内容的(流)函数。
特别是,如果以文本模式打开文件,那么I / O函数将在系统的外部(文本)行终止符的标准约定和内部换行符之间进行转换。如果您的程序对输入文件进行操作,您认为这些文件符合本地系统的行终止概念,并且您希望程序查看其输入文件,其中每行由换行符终止(单独) ,然后您需要以文本模式打开文件以进行该翻译。但请注意,这可能会产生其他影响。
如果您不能或不会以文本模式打开文件,那么您需要建立并处理&#34; line&#34;意味着你的程序。完全可以使它识别不同类型的行终止符,甚至是混合类型的行终止符。在这种情况下,知道Windows文本文件行由双字节序列"\r\n"
终止可能是有用的,而Unix行(包括OS X)文本文件由单个换行符终止。经典MacOS文本文件的行由单一回车终止,但您现在可能不需要担心这些。其他一些系统有其他约定或支持多种约定。