在C语言中读取文本文件
我有一个文本文件,如下所示:在C语言中读取文本文件,c,file,parsing,pointers,struct,C,File,Parsing,Pointers,Struct,我有一个文本文件,如下所示: sf5 sd6 sh7 或sh7 sd6 sf5(两种或其他可能的27种组合的任意顺序) 我试图从中提取值5、6和7 然而,我想以任何可能的顺序来做这件事,所以sf(somenumber)可以处于这3个位置中的任何一个,以及其他两个位置。因此,我尝试使用strstr作为我的宏之一 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ct
sf5 sd6 sh7
或sh7 sd6 sf5
(两种或其他可能的27种组合的任意顺序)
我试图从中提取值5、6和7
然而,我想以任何可能的顺序来做这件事,所以sf(somenumber)可以处于这3个位置中的任何一个,以及其他两个位置。因此,我尝试使用strstr
作为我的宏之一
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct test
{
char * values;
}test;
int main(int argc, char * argv[])
{
test t;
FILE * file;
char str[100];
int a,b,c;
if(argc > 1)
{
file = fopen(argv[1],"r");
if(file == NULL)
{
exit(1);
}
}
else
{
exit(1);
}
while(fgets(str,100,file) != NULL)
{
t.values = strtok(str," \n");
if(t.values == NULL)
exit(1);
if(strstr(t.values,"sf"))
{
a = atol(t.values+2); // the number two positions after the letter
}
if(strstr(t.values,"sd"))
{
b = atol(t.values+2); // the number two positions after the letter
}
if(strstr(t.values,"sh"))
{
c = atol(t.values+2); // the number two positions after the letter
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n",a,b,c);
}
}
#包括
#包括
#包括
#包括
类型定义结构测试
{
字符*值;
}试验;
int main(int argc,char*argv[])
{
试验t;
文件*文件;
char-str[100];
INTA、b、c;
如果(argc>1)
{
file=fopen(argv[1],“r”);
if(file==NULL)
{
出口(1);
}
}
其他的
{
出口(1);
}
while(fgets(str,100,file)!=NULL)
{
t、 值=strtok(str,“\n”);
如果(t.values==NULL)
出口(1);
if(strstr(t.值,“sf”))
{
a=atol(t.values+2);//字母后面的两个位置
}
if(strstr(t.值,“sd”))
{
b=atol(t.values+2);//字母后面的两个位置
}
if(strstr(t.值,“sh”))
{
c=atol(t.values+2);//字母后面的两个位置
}
printf(“a的值:%d\n b的值:%d\n c的值:%d\n”,a、b、c);
}
}
但是,输出仅对第一个值“sf5”正确,就好像第二个值没有被解析一样。另外,如果我把“sf5”移到末尾,它的值将为零,这同样没有意义
基本上,只有第一个
if
语句能够成功工作。任何帮助都将不胜感激 strstr函数给出搜索字符串的位置,如果找不到,则为NULL。您必须在atol函数中使用此结果才能获得关联的值
在下面的代码中,我使用变量token
存储strstr的结果:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char * argv[])
{
FILE * file;
char str[100];
int a,b,c;
if(argc > 1)
{
file = fopen(argv[1],"r");
if(file == NULL)
{
exit(1);
}
}
else
{
exit(1);
}
while(fgets(str,100,file) != NULL)
{
char *token;
token = strstr(str,"sf"));
if (token != NULL)
{
a = atol(token+2); // the number two positions after the letter
}
token = strstr(str,"sd"));
if (token != NULL)
{
b = atol(token+2); // the number two positions after the letter
}
token = strstr(str,"sh"));
if (token != NULL)
{
c = atol(token+2); // the number two positions after the letter
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n",a,b,c);
}
fclose(file);
}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
文件*文件;
char-str[100];
INTA、b、c;
如果(argc>1)
{
file=fopen(argv[1],“r”);
if(file==NULL)
{
出口(1);
}
}
其他的
{
出口(1);
}
while(fgets(str,100,file)!=NULL)
{
字符*令牌;
令牌=strstr(str,“sf”);
if(令牌!=NULL)
{
a=atol(token+2);//字母后面的第二个位置
}
令牌=strstr(str,“sd”);
if(令牌!=NULL)
{
b=atol(token+2);//字母后的第二个位置
}
令牌=strstr(str,“sh”);
if(令牌!=NULL)
{
c=atol(token+2);//字母后的第二个位置
}
printf(“a的值:%d\n b的值:%d\n c的值:%d\n”,a、b、c);
}
fclose(文件);
}
在每个if块之前打印t.values的值可能会有所帮助。
它表明t.值没有变化。只有第一个if块的表达式为true
如果你想使用。。。
“使用空指针对str1进行的后续调用将导致恢复先前保存的位置,并从该点开始搜索…”
因此,可以插入strtok调用(NULL,“\n”),如下所示:
t.values = strtok(str," \n");
if(strstr(t.values,"sf"))
{
a = atol(t.values+2); // the number two positions after the letter
}
t.values = strtok(NULL," \n"); // get pointer to next token
if(strstr(t.values,"sd"))
{
b = atol(t.values+2); // the number two positions after the letter
}
t.values = strtok(NULL," \n"); // get pointer to next token
if(strstr(t.values,"sh"))
{
c = atol(t.values+2); // the number two positions after the letter
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n",a,b,c);
现在输出是
Value of a: 5
Value of b: 6
Value of c: 7
您的代码有两个问题:
- 在使用时,不要使用返回指针,因此如果遇到字符串而不是在开头,它将在错误的位置查找数字
- 您不会循环查找后续的子字符串。由于
将字符串切碎,因此除了第一个分隔符之外,您将无法使用strtok()
找到任何内容strstr()
此代码(或您的代码)解决了找不到其中一个值的情况。因此,您应该将a、b、c初始化为defautlt值,例如0 使用
atol()
可以防止您知道程序失败的原因,请尝试char*endptr;a=strtol(t.值+2,&endptr,10);如果(*endptr!='\0')printf(“值'%s'未转换,因为无法转换下列字符'%s'\n',t.values+2,endptr))代码>。您没有检查t.values!=NULL
,如果strtok()
找不到'\n'
它将返回NULL
。如果您不介意使用外部库,您可以使用正则表达式非常轻松地解析它,使用类似于PCRE:。如果您想手动执行一些更易于维护的操作,而不考虑复杂性的增加,那么一个简单的起点就是阅读递归体面解析。不幸的是,当我最终学习如何使用PCRE这样的外部库时,实现它就太晚了。在第一次通过3If()
s之后,dot.values=strtok(NULL,“\n”)编码>并对3if()
s进行测试,直到t.values==NULL
。我已检查,t.values从不为NULL。
while (fgets(str, 100, file) != NULL)
{
t.values = strtok(str, " \t\n");
while (t.values) { // loop to analyse each substring
if (p = strstr(t.values, "sf"))
a = atol(p + 2); // the number two positions after the FOUND string
else if (p = strstr(t.values, "sd"))
b = atol(p + 2); // the number two positions after the letter
else if (p = strstr(t.values, "sh"))
c = atol(p + 2); // the number two positions after the letter
t.values = strtok(NULL, " \t\n");
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n", a, b, c);
}