繁体   English   中英

在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块的表达式为true。

如果要使用strtok来执行此操作,则...“随后对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

您的代码有两个问题:

  • 在使用strstr()您无需使用返回指针,因此,如果遇到字符串但不是在开头,它将在错误的位置查找数字;

  • 您不会在strtok()上循环以查找后续的子字符串。 strtok()将字符串切成段时,使用strstr()不会超出第一个分隔符;

这是一种基于您原始方法的替代解决方案(但是由于我打字速度很慢,在此期间,已经有两个其他有价值的解决方案;-))

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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM