我正在编写一个小程序,它从 csv 文件中读取 n 个最新行,然后将这些行打印到终端。但是我偶然发现了一个我无法弄清楚的问题。 我尝试从文件的顶部和底部开始读取,并使用 \n 和 \r 指示计算行数。
我按照建议将常量从“0x0A”更改为“\n”,并将“-1”更改为宏 EOF。变量“字母”从 char 变为 int。
代码:
#include <stdio.h>
#include <string.h>
int main() {
char *token;
int i = 3;
int j = 0;
int linebreakes = 0;
char line[200];
int letter = 0;
int max_rows = 16;
int eof = 0;
char *strings[16];
FILE *fp;
fp = fopen("C:\\testCSV\\testfile.csv", "rb");
printf("j = %d\n", j);
while (linebreakes < max_rows && eof == 0) {
fseek(fp, -i, SEEK_END);
letter = fgetc(fp);
printf("LINE BREAKES [%d]\n", linebreakes);
i++;
printf("i = %d\n", -i);
if (letter == EOF) { //EOF, 0xFF, -1
printf("EOF DETECTED\n");
fseek(fp, (-i + 2), SEEK_END);
eof = 1; //exit while loop
}
if (letter == '\n') { //0x0A == LF
printf("/n detected!!\n");
linebreakes++;
fseek(fp, -i, SEEK_END);
letter = fgetc(fp);
}
if (letter == '\r') { //0x0D == CR
printf("/r detected!!!\n");
i++;
}
}
printf("letter = %c on %d\n", letter, i);
if (!eof) {
fseek(fp, (-i + 3), SEEK_END);
}
printf("The latest %d rows in the file contains the following values: \n\n",
(linebreakes + 1));
while (fgets(line, sizeof(line), fp) != NULL) {
printf("line = %s\n", line);
token = strtok(line, ",");
printf("token = [%s] before while != null\n", token);
while (token != NULL) {
printf("token = %s\n", token);
token = strtok(NULL, ",");
j++;
}
}
if (feof(fp)) {
printf("end of FILEEEE");
}
if (ferror(fp)) {
printf("error indicator set");
}
fclose(fp);
printf("file closed\n");
}
原理是通过从文件末尾倒退并计算换行符来读取文件中最新的 n 行。请注意,尚未添加错误处理。当换行符达到要求读取的行数时,我开始使用 fgets 从那里读取并挑选要打印的标记。
这很有效,直到我在一行中添加几个字符。然后它只是跳转到 fclose() 并打印“文件关闭”而不打印任何行。我注意到它的工作阈值是文件大小为 514 字节,但这可能是巧合。
如果我向“line”数组添加更多元素,则没有任何变化。 正如您在程序末尾看到的那样,我尝试读取 ferror 是否出错。但我没有收到错误,只有文件结尾。
该文件目前有 16 行,为了让您了解文件的外观,其中包含最少字符的行如下所示:
$1,20210125 12:59,t1,t2,t3
其中包含最多字符的行如下所示:
$11,20210125 14:18,testagain,heyhey,hje
我只需要在第一行添加“a”即可使程序停止工作。 (或任何其他行,都没有关系)
我正在使用 CRLF 行尾的 Windows 操作系统。
我一定是做错了什么,但我不知道是什么,因为我是 C 编程的新手。
当然,我搜索过是否可以找到有类似问题的人。但我没有找到任何可以帮助我的东西。