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。