C - 读取文件并将strtok拆分为数组

时间:2017-10-01 12:18:20

标签: c arrays malloc strtok

所以我试图读取一个由|分隔的一系列单词和句子的文件,并在将令牌放入数组时将它们与strtok()分开。然后打印数组以检查内容是否正确 但是,输出输出不正确 这是我的代码。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char ** argv)
{
    FILE *fp;
    char *str=malloc(80*sizeof(char));
    int count=0;
    char *tokenArray[100];
    int i=0;
    int j=0;
    char *token = strtok(str, "|");

    printf("Loading stock...\n");
    fp = fopen(argv[1], "r");
    while(fgets(str, sizeof(str),fp)!=NULL){        
        tokenArray[0]=strtok(str,"|");

        for(i=1; i<200; i++){
            if((tokenArray[i]=strtok(NULL,"|")) ==NULL)
                break;
        }
        count=i;

        for(i=0; i<count;i++){
            printf("%d: %s\n",i,tokenArray[i]);
        }
    }
    return EXIT_SUCCESS;
}

输出结果如下:

Loading stock...
0: I0001
1: M
0: eat Pie
0: Yummy
0: Beef in
0:  Gravy
0: surroun
0: ded by
0: pastry
0: 3.50
1: 50
0:

0: I0002
1: A
0: pple Pi
0: e
1: Delic
0: ious St
0: ewed Ap
0: ple in
0: a Yummy
0:  Pastry
0:  envelo
0: pe
1: 3.00
0: 20

哪个不好。 但是,如果我调整它,那么str是静态的char str[80];,它会运行,输出是

0: I0001
1: Meat Pie
2: Yummy Beef in Gravy surrounded by pastry
3: 3.50
4: 50

但是为了我的任务,我必须使用malloc()。 出了什么问题?

1 个答案:

答案 0 :(得分:1)

请查看内容注释的代码的固定版本。你的主要问题是对sizeof(str)的错误解释(事实上,这解释了为什么当str是一个字符数组而不是一个指针时它起作用),但我也解决了一些提到的问题。对原始问题的评论。此外,如果您有多行需要令牌化,您可能想要调查strtok()实际上如何工作 - 如Weather Vane所述,如果您想保留旧令牌,它将不适用于多行。如果那是作业的要求,我将把这个问题的正确解决方案作为OP的练习。

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

#define BUF_SIZE 80

int main(int argc, char ** argv)
{
    FILE *fp;
    char *str=malloc(BUF_SIZE*sizeof(char));
    int count=0;
    char *tokenArray[100];
    int i=0;
    int j=0;
    // See comment by Weather Vane
    //char *token = strtok(str, "|");
    char *token;

    printf("Loading stock...\n");
    fp = fopen(argv[1], "r");
    // sizeof(str) == sizeof(char *) == 8 on x86_64, NOT 80 as you assumed
    //while(fgets(str, sizeof(str),fp)!=NULL){
    while(fgets(str, BUF_SIZE, fp)!=NULL){

        tokenArray[0]=strtok(str,"|");

        // See comment by Martin James about array bounds
        //for(i=1; i<200; i++){
        for(i=1; i < sizeof(tokenArray)/sizeof(tokenArray[0]); i++){
            if((tokenArray[i]=strtok(NULL,"|")) ==NULL)
                break;
        }
        count=i;

        for(i=0; i<count;i++){
            printf("%d: %s\n",i,tokenArray[i]);
        }
    }
    return EXIT_SUCCESS;
}

如果test.txt包含:

,则可以正常工作
I0001|Meat Pie|Yummy Beef in Gravy surrounded by pastry|3.50|50

被称为:

$./tmp test.txt

输出:

Loading stock...
0: I0001
1: Meat Pie
2: Yummy Beef in Gravy surrounded by pastry
3: 3.50
4: 50