C语言 用于打印文件中的行数和列数的代码.为什么它适用于Windows Mingw gcc环境,而不适用于Linux?



代码在Windows上的任何编译器上都可以很好地工作,但在Linux上则不能。在 Linux 上,它返回超过两倍的行数和负数的列数。Win8.1 x86_64,Linux 16.04 64位。我在Windows(MINGW)上有GCC v5.3,但在Linux上有GCC v5.4.0。

#include <stdio.h>
// count Lines of a file
size_t countLinesOfFile(char *fileName)
{
FILE *fp = fopen(fileName, "r");
char ch;
size_t lines = 0;
do {
ch = fgetc(fp);
if(ch == 'n' || ch == 'r')
lines++;
} while (ch != EOF);
//while (!feof(fp))
// if last line doesn't end with a new line character! augment No of lines
if(ch != 'n' || ch != 'r')
lines++;
fclose(fp);
return lines;
}
// assuming that the file has equal number of columns for all its lines
// (or just 1 line)
size_t countColumnsOfFile(char *fileName)
{
FILE *fp = fopen(fileName, "r");
char ch;
size_t columns = 0;
while ((ch != 'n' || ch != 'r') && ch != EOF) { // we only want to count one line so which ever comes first
ch = fgetc(fp);
columns++;
}
columns--;
//feof(fp) = found end of file, returns non zero(true) if found
fclose(fp);
return columns;
}

当您同时读取rn时,您正在递增lines。在 Windows 上创建文本文件时,它使用 CRLF 作为换行符序列,但 Cstdio库将这些文本组合成单个n字符(除非您以二进制模式打开该文件)。

Unix只使用LF作为换行符。如果将文件从Windows复制到Unix,它将分别读取CR和LF作为单独的字符,rn。您的代码会为它们中的每一个递增line,因此您需要对每行进行两次计数。对于您在 Unix 上创建的文件,不会发生这种情况。

所以你应该只数n字符。只要您以文本模式(默认)打开文件,这是您应该看到的唯一换行符。需要 C 库将操作系统的换行符序列转换为此字符。

顺便说一句,这条线在两个方面是错误的:

// if last line doesn't end with a new line character! augment No of lines
if(ch != 'n' || ch != 'r')

首先,如果要测试一个字符是否nr,则应使用&&,而不是||。请参阅为什么对一个变量对多个值进行不相等检查总是返回 true?

其次,循环在ch == EOF时结束,因此它将始终不等于rn。如果要测试最后一行的结尾方式,则需要在重复ch = fgetc(fp);赋值之前将每个字符保存到另一个变量中。

列计数代码具有相同的问题,即测试与任何列表都不匹配的字符。它应该是

while (ch != 'n' && ch != 'r' && ch != EOF) { // we only want to count one line so which ever comes first

我修复了它。当时我对此有点困惑。这是代码,简单明了。它在MAC上不起作用(您必须将"n"替换为"r")。

// count lines of a file
size_t countLinesOfFile(char *fileName)
{
FILE *fp = fopen(fileName, "r");
char ch;
size_t lines = 1; // every file starts from line #1
do {
ch = fgetc(fp);
if(ch == 'n')
lines++;
} while (ch != EOF);
//while (!feof(fp))
fclose(fp);
return lines;
}
// assuming that the file has equal ammount of columns
// calculate columns of a file (maximum ammount of columns in any given line)
size_t countColumnsOfFile(char *fileName)
{
FILE *fp = fopen(fileName, "r");
char ch;
size_t columns = 0;
while (ch != 'n' && ch != EOF) {
ch = fgetc(fp);
columns++;
}
// note that #(chars in the line) = #(columns) - 1
fclose(fp);
return columns;
}

int main()
{
printf("lines = %dn", countLinesOfFile("file.txt"));
printf("columns = %dn", countColumnsOfFile("file.txt"));
}

相关内容

最新更新