C语言读取文本文件
Reading in text file in C
我有一个文本文件如下:
sf5 sd6 sh7
或sh7 sd6 sf5
(两者的任意顺序或其他可能的 27 种组合)。
我正在尝试从中提取值 5,6, and 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);
}
}
然而,只有第一个值 "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);
}
在每个 if 块之前打印 t.values 的值可能会有所帮助。
它表明 t.values 没有变化。只有第一个 if 块的表达式为真。
如果您想使用 strtok...
"Subsequent calls with a null pointer for str1 will cause the previous position saved to be restored and begins searching from that point..."
所以也许插入 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
您的代码有两个问题:
在使用strstr()
时不使用return指针,这样如果遇到字符串但不在开头,它会寻找数字在错误的地方;
您无需循环 strtok()
来查找后续子字符串。由于 strtok()
将字符串分成几部分,因此除了 strstr()
的第一个分隔符之外,您将找不到任何其他内容;
这是一个基于您原来方法的替代解决方案(但由于我打字速度很慢,与此同时,已经有 2 个其他有价值的解决方案 ;-))
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);
}
现在如果你输入 aaasf5 他会为 a 找到 5,而之前它找到 0。
此代码(也不是您的代码)解决了找不到其中一个值的情况。因此,您应该将 a、b、c 初始化为默认值,例如 0。
我有一个文本文件如下:
sf5 sd6 sh7
或sh7 sd6 sf5
(两者的任意顺序或其他可能的 27 种组合)。
我正在尝试从中提取值 5,6, and 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);
}
}
然而,只有第一个值 "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);
}
在每个 if 块之前打印 t.values 的值可能会有所帮助。 它表明 t.values 没有变化。只有第一个 if 块的表达式为真。
如果您想使用 strtok... "Subsequent calls with a null pointer for str1 will cause the previous position saved to be restored and begins searching from that point..."
所以也许插入 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
您的代码有两个问题:
在使用
strstr()
时不使用return指针,这样如果遇到字符串但不在开头,它会寻找数字在错误的地方;您无需循环
strtok()
来查找后续子字符串。由于strtok()
将字符串分成几部分,因此除了strstr()
的第一个分隔符之外,您将找不到任何其他内容;
这是一个基于您原来方法的替代解决方案(但由于我打字速度很慢,与此同时,已经有 2 个其他有价值的解决方案 ;-))
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);
}
现在如果你输入 aaasf5 他会为 a 找到 5,而之前它找到 0。
此代码(也不是您的代码)解决了找不到其中一个值的情况。因此,您应该将 a、b、c 初始化为默认值,例如 0。