c - 如何在 C 中以已知格式逐行读取文件

标签 c file input io output

文件格式如下

month day hour:min:sec process: message

示例:

Aug 13 12:20:34 automount[1478]: add_host_addrs: hostname lookup failed

我正在尝试逐行阅读,对于阅读的每一行,确定“消息”是否包含“失败”一词。

运行时没有输出,请告诉我哪里出错了,谢谢!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define INPUT_SIZE 80

int main()
{
    FILE* file = fopen("logfile", "r");

    char month;
    int day, hour, min, sec;
    char process[INPUT_SIZE];
    char message[INPUT_SIZE];
    char line[INPUT_SIZE];


    if (fgets(line, INPUT_SIZE, file) == NULL)
    {
        perror("Error opening file");
    }
    else
    {
        sscanf("%3s %2d %2d:%2d:%2d %s %s", &month, &day, &hour, &min, &sec, &process, &message);
        printf("%3s %2d %2d:%2d:%2d %s %s\n", month, day, hour, min, sec, process, message);

        while (strstr(message, "fail"))
        {
            /* do something */
        }
    }


    fclose(file);
    if(line == NULL)
    {
        free(line);
    }
    return 0;
}

最佳答案

您对 sscanf() 的使用不正确。

使用

sscanf(line, "%3s %2d %2d:%2d:%2d %s %[^\n]", month, &day, &hour, &min, &sec, process, message);

其中 line 是您要扫描的字符串。

代替

sscanf("%3s %2d %2d:%2d:%2d %s %s", &month, &day, &hour, &min, &sec, &process, &message);

请注意,为了读取字符串(使用 %s),您使用字符数组而不是单个字符。 由于 month 必须包含多个字符,因此它应该是一个字符数组。

由于数组的名称衰减为其基地址,因此在提供字符串地址时不需要 & 运算符。
即,...%s %s", month, ...process, message)

输入字符串的message 部分由多个单词组成。通常 fscanf() 会在第一个空格或换行符后停止读取。要继续扫描直到换行,您可以使用 %[^\n]。它会一直读到遇到换行符。这样 message 将整个 hostname lookup failed 而不是 hostname

现在 message 有完整的消息,strstr(message, "fail") 将返回非 NULL 并且控件将进入while 循环。

line 分配在栈上而不是堆上。你不应该做 free(line)

并且缓冲区 line 的大小将大于其他字符串,这些字符串应该保存使用 fgets() 读入 line 的部分数据。因此,可能没有必要对所有字符串使用相同的大小。

编辑:您可以使用 printf() 输出类似

printf("%s %02d %02d:%02d:%02d %s %s\n", month, day, hour, min, sec, process, message);

%02d 表示如果数字少于 2 位,则在数字前加零,使总位数为 2。

作为Artemy Vysotsky注释,可以检查 sscanf() 的返回值以查找是否所有分配都成功。 sscanf() 返回成功赋值的次数(或 EOF 输入失败)。在这种情况下,它必须是 7。如果不是,则发生了一些错误。

关于c - 如何在 C 中以已知格式逐行读取文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46471813/

相关文章:

c - 蓝牙通信延迟大

c - 有趣的位掩码形成

arrays - 在python中将stdin行转换为 "float/int"数组的更简单方法

c - 我未编译一些汇编代码。它有什么作用?

c++ - 实时检测图像是否不同

java - Java 中的值匹配和降维

html - 将目录重定向到目录中的文件

c - 从c中的文件导入所有字符串

r - 使用直方图作为 R 中的输入

input - 十六进制数字键盘