从文件中逐行读取并保存在列表C中

时间:2016-03-08 11:57:59

标签: c list file

我的问题是从一个包含100行的文件中读取,每行包含4个字段(用4个空格分隔),如下所示:

0007 0007 NOVO BANCO, SA Bancos

0008 0008 BANCO BAI EUROPA, SA Bancos

0010 0010 BANCO BPI, SA Bancos

等...

执行此操作后,我必须将其保存在链接列表中。

我有这个:

struct list{
    int code1;
    int code2;
    char name[100];
    char type[100];
    struct list *next, *current;    
};

int main()
{

    FILE *fp1;
    struct list iban;

    fp1 = fopen("ibanlist.txt", "r");
    if(fopen == NULL)
    {
         printf("Error!");
    }

    fscanf(fp1, /*what should i do here?*/, iban.code1, iban.code2, iban.name, iban.type);
    //should i use fgets and sscanf instead?

    fclose(fp1);
    return 0;
}

我的问题是如何从带有空格的文件中读取。例如,在第三个字段中,它在','之后有一个空格。也是我第一次使用列表,任何人都可以给我一个良好的开端如何做到这一点?

2 个答案:

答案 0 :(得分:1)

您可以尝试在三个或更多连续空格处标记字符串。然后,您可以使用strtol或类似函数转换ID。

这样做的一种方法是使用strstr搜索三个空格,然后跳过空格。

以下简短程序实现strtok hat的变体在三个或更多空格处分割字符串。与strtok一样,它会修改您的字符串,因此请确保传递可修改的字符数组。

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>

    char *token(char *str)
    {
        static char *p;
        char *res;

        if (str) p = str;
        if (p == NULL) return p;

        while (*p == ' ') p++;
        if (*p == '\0') return NULL;
        res = p;

        p = strstr(p, "   ");

        if (p && *p) {
            *p = '\0';
            p++;
        }

        return res;
    }

    int main()
    {
        char str[] = "0008   0008    BANCO BAI EUROPA, SA    Bancos";
        char *t;

        t = token(str);
        while (t) {
            puts(t);
            t = token(NULL);
        }

        return 0;
    }

答案 1 :(得分:1)

这使用strstr来标记输入字符串。数据中的第一个分隔符只有3个空格,其余的是4个,所以在每种情况下我都会查找3,然后超过所有连续的空格。

#include <stdio.h>
#include <string.h>

struct list{
    int code1;
    int code2;
    char name[100];
    char type[100];
};

int main(void)
{
    FILE *fp;
    char str [1000];
    char *aptr, *bptr, *cptr;
    struct list rec;

    if ((fp = fopen("file.txt", "rt")) == NULL)
        return 1;

    while(fgets(str, sizeof str, fp) != NULL) {
        // break the input line
        aptr = strstr(str, "   ");              // isolate first field
        if(aptr == NULL)
            return 1;
        *aptr++ = '\0';
        while (*aptr == ' ')
            aptr++;

        bptr = strstr(aptr, "   ");             // isolate second field
        if(bptr == NULL)
            return 1;
        *bptr++ = '\0';
        while (*bptr == ' ')
            bptr++;

        cptr = strstr(bptr, "   ");             // isolate third field
        if(cptr == NULL)
            return 1;
        *cptr++ = '\0';
        while (*cptr == ' ')
            cptr++;

        cptr [ strcspn(cptr, "\r\n") ] = 0;    // remove trailing newline etc

        // extract the data
        if(sscanf(str, "%d", &rec.code1) != 1)
            return 1;
        if(sscanf(aptr, "%d", &rec.code2) != 1)
            return 1;
        strcpy(rec.name, bptr);
        strcpy(rec.type, cptr);

        // print the result
        printf("%d/%d/%s/%s\n", rec.code1, rec.code2, rec.name, rec.type);
    }
    fclose(fp);
    return 0;
}

节目输出:

7/7/NOVO BANCO, SA/Bancos
8/8/BANCO BAI EUROPA, SA/Bancos
10/10/BANCO BPI, SA/Bancos