如何在C中的文本文件中读取由标点符号分隔的变量

时间:2018-03-28 20:49:44

标签: c file-io binary-search-tree read-write

我想知道如何从文本文件中读取数据,该文件的数据用逗号分隔。

例如,文本文件的第1行显示:(Integer,Name Surname, IntegerArray)

这是1行:123456789,Jonh Brown,123456434-4325234-235234-42345234

typedef struct BST
{
    long long ID;
    char *name;
    char *surname;
    long long *friendsID;
    struct BST *left;
    struct BST *right;
}BST;

从文件中读取:

do
{
    c = fscanf(fp,"%I64d%*c%s%s",&ID,name,surname);
    if (c != EOF)
        root=insertNewUser(root,ID,name,surname);
} while (c != EOF);

newNodeTemp->ID = ID;
newNodeTemp->name = (char*)calloc(strlen(name),sizeof(char));
newNodeTemp->surname = (char*)calloc(strlen(surname),sizeof(char));
strcpy(newNodeTemp->name,name);
strcpy(newNodeTemp->surname,surname);

但是我不知道如何将它作为数组导入BST->没有'-'(连字符)的朋友。

这部分:123456434-4325234-235234-42345234

我将数组的朋友定义为指针。因为我们不知道它的大小。我将使用动态内存分配...

1 个答案:

答案 0 :(得分:1)

如果我理解你的问题,你有一个带有用户信息的CSV和该用户的朋友,其中朋友被编码为连字符分隔的朋友ID列表作为该行中的第三个字段,那么你可以使用可重入版本strtok(名为strtok_r)的组合,用于分隔逗号分隔的字段,然后在外部循环中使用对strtok的调用来分隔连字符分隔值。

注意,strtok_r需要额外的" 保存指针"作为其第三个参数,以便您可以在对strtok_rstrtok的差异实例进行中间调用之后恢复对该strtok_r实例的调用,以进行其他分离。

鉴于你的行:

"123456789,Jonh Brown,123456434-4325234-235234-42345234"

其中123456789是ID,Jonh Brown是名称,123456434-4325234-235234-42345234是朋友ID列表,您可以通过保持字段数来解析该行和各个朋友并在你的tokinzation循环中调用strtok的单独实例来分隔连字符上的朋友。

一个简短的例子是:

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

#define FRIENDS 3

int main (void) {

    char line[] = "123456789,Jonh Brown,123456434-4325234-235234-42345234",
        *delims = ",\n",    /* strtok_r delimiters for tokens */
        *p      = line,     /* pointer to line */
        *sp     = p;        /* save pointer for reentrant strtok_r */
    int count = 0;

    /* must use reentrant version of strtok to nest strtok use for friends */
    p = strtok_r (line, delims, &sp);  /* 1st call uses name of buffer */
    count++;

    while (p) {             /* outputer tokenization loop */
        printf ("token: '%s'\n", p);
        if (count == FRIENDS) {
            char *pf = calloc (strlen (p) + 1, 1),  /* pointer to friends   */
                *delim2 = "-\n",                    /* delims for friends   */
                *f;                                 /* pointer preserves pf */
            if (!pf) {
                perror ("malloc-pf");
                exit (EXIT_FAILURE);
            }
            strcpy (pf, p);                 /* copy friends token to pf */
            f = pf;                         /* set f, to pf, to preserve pf */
            f = strtok (f, delim2);         /* regular strtok OK for friends */
            if (f)
                printf ("friends:\n");
            while (f) {     /* friends tokenization loop */
                printf ("    %s\n", f);
                f = strtok (NULL, delim2);  /* subsequent calls use NULL */
            }
            free (pf);      /* free allocated memory at preserved address */
            count = 0;      /* reset count */
        }
        p = strtok_r (NULL, delims, &sp);  /* subsequent calls use NULL */
        count++;
    }

    return 0;
}

注意:,因为strtok修改原始字符串并使其使用的指针前进,您必须复制好友令牌,并保留指向该起始地址的指针为朋友分配了令牌(pf),以便在您完成分离朋友后可以释放它。)

另请注意:如果您的系统提供strdup,则可以通过简单调用{{1}来替换两个calloc (strlen (p) + 1, 1)strcpy (pf, p);来电但请注意,由于char *pf = strdup(p);动态分配,您仍应在通话后验证strdup

示例使用/输出

if (!pf)

仔细看看,如果您有其他问题,请告诉我。