简体   繁体   English

在C中读取文本文件

[英]Reading in text file in C

I've got a text file as follows: 我有一个文本文件,如下所示:

sf5 sd6 sh7 

or sh7 sd6 sf5 (any order of the two or the other possible 27 combinations). sh7 sd6 sf5 (两个或其他任意可能的27种组合的任何顺序)。

I'm trying to extract the values 5,6, and 7 from it However, I want to do this in any order possible, so sf(somenumber) can be in any of those 3 positions, as well as the other two. 我正在尝试从中提取值5,6, and 7但是,我想以任何可能的顺序执行此操作,因此sf(somenumber)可以位于这3个位置中的任何一个以及其他两个位置中。 Thus, I'm trying to use strstr as one of my macros. 因此,我试图将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);

    }    
}

However the output is only correct for the first value "sf5", as if the second two aren't being parsed. 但是,输出仅对第一个值“ sf5”正确,就好像没有对后两个值进行解析一样。 Also, if I move "sf5" to the end, it's value provides to be zero which again makes no sense. 另外,如果我将“ sf5”移到末尾,则它的值将设置为零,这再次没有意义。

Basically, only the first if statement ever works successfully. 基本上,只有第一个if语句才能成功运行。 Any help would be much appreciated! 任何帮助将非常感激!

The strstr function gives the position of the searched string or NULL if it's not found. strstr函数提供搜索到的字符串的位置;如果找不到,则为NULL。 You have to use this result in the atol function in order to get the value associated. 您必须在atol函数中使用此结果才能获取关联的值。

In the code below I use the variable token to store the result of strstr: 在下面的代码中,我使用变量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);    
}

It may be helpful to print the value of t.values before each if block. 在每个if块之前打印t.values的值可能会有所帮助。 It shows that t.values does not change. 它表明t.values不变。 Only the first if block's expression will be true. 只有第一个if块的表达式为true。

If you want to do this using 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来执行此操作,则...“随后对str1使用空指针的调用将导致恢复先前保存的位置并从该点开始搜索...”

So maybe insert calls of strtok(NULL, " \\n"), like this: 因此,也许插入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);

Now the output is 现在的输出是

Value of a: 5
 Value of b: 6
 Value of c: 7

Your code has two issues : 您的代码有两个问题:

  • in the use of strstr() you don't use the return pointer, so that if encountering the string but not at the beginning, it vwill look for the digit at the wrong place; 在使用strstr()您无需使用返回指针,因此,如果遇到字符串但不是在开头,它将在错误的位置查找数字;

  • you don't loop on strtok() to find the subsequent substrings. 您不会在strtok()上循环以查找后续的子字符串。 As strtok() cuts the string in pieces, you won't find anythning beyond the first separator with strstr() ; strtok()将字符串切成段时,使用strstr()不会超出第一个分隔符;

Here an alternative solution based on your original approach (but as I'm very slow in typing, in the meanttime there are already 2 other valuable solutions ;-) ) 这是一种基于您原始方法的替代解决方案(但是由于我打字速度很慢,在此期间,已经有两个其他有价值的解决方案;-))

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);
}

Now if you enter aaasf5 he will find 5 for a, while it found 0 before. 现在,如果您输入aaasf5,他将为a找到5,而之前则为0。
This code (nor yours) address the case where one of the value isn't found. 此代码(也不包含您的代码)解决了找不到其中一个值的情况。 You should therefore initialize your a,b,c to a defautlt value, for example 0. 因此,您应该将a,b,c初始化为默认值,例如0。

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

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