Nik*_*kos 0 c linux gcc cross-platform file
代码适用于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;
}
Run Code Online (Sandbox Code Playgroud)
你递增lines
,当你阅读这两个\r
和\n
.在Windows上创建文本文件时,它使用CRLF作为换行符序列,但C stdio
库将这些组合成单个\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')
Run Code Online (Sandbox Code Playgroud)
首先,如果你想测试一个字符不是\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
Run Code Online (Sandbox Code Playgroud)