代码在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;
}
当您同时读取r
和n
时,您正在递增lines
。在 Windows 上创建文本文件时,它使用 CRLF 作为换行符序列,但 Cstdio
库将这些文本组合成单个n
字符(除非您以二进制模式打开该文件)。
Unix只使用LF作为换行符。如果将文件从Windows复制到Unix,它将分别读取CR和LF作为单独的字符,r
和n
。您的代码会为它们中的每一个递增line
,因此您需要对每行进行两次计数。对于您在 Unix 上创建的文件,不会发生这种情况。
所以你应该只数n
字符。只要您以文本模式(默认)打开文件,这是您应该看到的唯一换行符。需要 C 库将操作系统的换行符序列转换为此字符。
顺便说一句,这条线在两个方面是错误的:
// if last line doesn't end with a new line character! augment No of lines
if(ch != 'n' || ch != 'r')
首先,如果要测试一个字符是否n
或r
,则应使用&&
,而不是||
。请参阅为什么对一个变量对多个值进行不相等检查总是返回 true?
其次,循环在ch == EOF
时结束,因此它将始终不等于r
和n
。如果要测试最后一行的结尾方式,则需要在重复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"));
}