如何在C中以已知格式逐行读取文件
该文件的格式如下如何在C中以已知格式逐行读取文件,c,file,input,io,output,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
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;
}
#包括
#包括
#包括
#定义输入_大小80
int main()
{
文件*FILE=fopen(“日志文件”,“r”);
炭月;
整数天,小时,分钟,秒;
字符处理[输入大小];
字符消息[输入大小];
字符行[输入大小];
if(fgets(行、输入大小、文件)==NULL)
{
perror(“打开文件时出错”);
}
其他的
{
sscanf(“%3s%2d%2d:%2d:%2d%s%s”、&month、&day、&hour、&min、&sec、&process、&message);
printf(“%3s%2d%2d:%2d:%2d%s%s\n”,月、日、小时、分钟、秒、进程、消息);
while(strstr(消息“fail”))
{
/*做点什么*/
}
}
fclose(文件);
如果(行==NULL)
{
自由线;
}
返回0;
}
您使用的sscanf()
不正确
使用
其中,line
是要扫描的字符串
而不是
sscanf("%3s %2d %2d:%2d:%2d %s %s", &month, &day, &hour, &min, &sec, &process, &message);
请注意,为了读入字符串(使用%s
),需要使用字符数组而不是单个字符。
由于month
必须包含多个字符,因此它应该是一个字符数组
当数组的名称衰减为其基址时,在提供字符串的地址时,不需要&
运算符。例如,
…%s%s',月份,…进程,消息)
输入字符串的消息
部分由多个单词组成。通常fscanf()
会在第一个空格或换行符后停止读取。要一直扫描到换行符,可以使用%[^\n]
。它将一直读取,直到遇到换行符。这样,消息
将使整个主机名查找失败
,而不仅仅是主机名
既然message
已经有了完整的消息,strstrstr(message,“fail”)
将返回非NULL
,控件将进入while
循环
line
是在堆栈上分配的,而不是在堆上分配的。您不应该执行free(line)
并且缓冲区行
的大小将大于其他字符串,这些字符串应该保存使用fgets()
读取到行
中的部分数据。因此,可能不需要对所有字符串使用相同的大小
编辑:您可以使用printf()
进行如下输出
printf("%s %02d %02d:%02d:%02d %s %s\n", month, day, hour, min, sec, process, message);
%02d
表示如果数字中的数字少于2位,则在数字前加零,使数字总数为2
如注释所述,可以检查
sscanf()
的返回值,以确定所有分配是否成功。sscanf()
返回成功分配的数量(或输入失败时的EOF
)。在这种情况下,它必须是7
。如果没有发生错误。想象我正在读取一个.csv“文件,其中包含您要查找的数据,只需执行此操作。如果它不是第一行,我想您可以设法解析文件的其余部分,直到您得到“fail”或任何其他您想要的单词
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int len = sending();
char *firstline;
int i = 0;
char buf[0];
int rd ;
int fd = open("test.csv", O_RDONLY);
rd = read(fd, buf, 1);
firstline = malloc(sizeof(char) * len);
while (i != len)
{
firstline[i] = buf[0];
i++;
rd = read(fd, buf, 1);
}
firstline[i] = '\0';
printf("%s\n", firstline);
int contains = 0;
i = 0;
while (firstline[i]) //loop that verifies if it contains the word "fail"
{
if (firstline[i] == 'f' && firstline[i + 1] == 'a' && firstline[i + 2] == 'i' && firstline[i + 3] == 'l')
++contains;
i++;
}
return (0);
}
int sending()
{
int fd = open("test.csv", O_RDONLY);
char buf[1];
int r = 0;
r = read(fd, buf, 1);
int len = 0;
while (buf[0] != '\n')//reading until '\n' and getting size to malloc
{
len++;
r = read(fd, buf, 1);
}
return len;
}
#包括
#包括
#包括
#包括
#包括
#包括
int main()
{
int len=sending();
字符*第一行;
int i=0;
char-buf[0];
国际公路;
int fd=open(“test.csv”,仅限ordu);
rd=读取(fd,buf,1);
第一行=malloc(sizeof(char)*len);
而(i!=len)
{
第一行[i]=buf[0];
i++;
rd=读取(fd,buf,1);
}
第一行[i]='\0';
printf(“%s\n”,第一行);
int=0;
i=0;
while(firstline[i])//循环,用于验证是否包含单词“fail”
{
如果(一线[i]='f'和一线[i+1]='a'和一线[i+2]='i'和一线[i+3]='l')
++包含;
i++;
}
返回(0);
}
int发送()
{
int fd=open(“test.csv”,仅限ordu);
char-buf[1];
int r=0;
r=读取(fd,buf,1);
int len=0;
while(buf[0]!='\n')//读取到'\n',并将大小获取到malloc
{
len++;
r=读取(fd,buf,1);
}
回程透镜;
}
1)char month;
-->char month[4];
2)sscanf(“%3s%2d%2d:%2d:%2d%s%s”…
-->sscanf(line),“%3s%2d%2d:%2d%s%s”…
对sscanf的调用完全错误-第一个参数是输入字符串,然后是格式如果(line==NULL){free(line)}
将被删除。只有免费的
动态创建的东西,例如使用malloc
顺便说一句:行
永远不能为空3)%s“,&month
-->%[^\n]”,month
当fgets失败时,你究竟为什么会发出打开文件的错误消息?如果fopen
失败,请调用peror(“文件”)
。如果fgets失败,也可以调用perror(“日志文件”)
,并期望收到与打开文件无关的错误消息。谢谢。您知道如何将输出修改为“00”格式吗?例如,输出看起来像:“Aug 26 3:47:1”,而它应该是“Aug 26 03:47:01”“非常感谢您的帮助!您应该在使用前检查sscanf的返回值values@ArtemyVysotsky最后两个字符串长度未知。如何检查返回值?@J…S您混淆了scanf和printf
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int len = sending();
char *firstline;
int i = 0;
char buf[0];
int rd ;
int fd = open("test.csv", O_RDONLY);
rd = read(fd, buf, 1);
firstline = malloc(sizeof(char) * len);
while (i != len)
{
firstline[i] = buf[0];
i++;
rd = read(fd, buf, 1);
}
firstline[i] = '\0';
printf("%s\n", firstline);
int contains = 0;
i = 0;
while (firstline[i]) //loop that verifies if it contains the word "fail"
{
if (firstline[i] == 'f' && firstline[i + 1] == 'a' && firstline[i + 2] == 'i' && firstline[i + 3] == 'l')
++contains;
i++;
}
return (0);
}
int sending()
{
int fd = open("test.csv", O_RDONLY);
char buf[1];
int r = 0;
r = read(fd, buf, 1);
int len = 0;
while (buf[0] != '\n')//reading until '\n' and getting size to malloc
{
len++;
r = read(fd, buf, 1);
}
return len;
}