如何在C中的文本文件中读取由标点符号分隔的变量
How to read variable separated by punctuations in a text file in C
我想知道如何从用逗号分隔数据的文本文件中读取数据。
例如,文本文件的第 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->friends。
这部分:123456434-4325234-235234-42345234
我把数组的friends定义为指针。因为我们不知道它的大小。我将使用动态内存分配...
如果我理解你的问题,你有一个包含用户信息和该用户的朋友的 CSV,其中朋友被编码为连字符分隔的 friend-IDs 列表作为行中的第三个字段,那么您可以使用 strtok
的 re-entrant 版本(名为 strtok_r
)的组合来分隔逗号分隔的字段,而不是在外循环中使用对 strtok
的调用来分隔连字符分隔值。
请注意,strtok_r
需要一个额外的“保存指针”作为其第三个参数,以便您可以在拥有后恢复对 strtok_r
实例的调用为替代分离目的对 strtok
或 strtok_r
的差异实例进行了中间调用。
鉴于您的行:
"123456789,Jonh Brown,123456434-4325234-235234-42345234"
其中123456789
是ID,Jonh Brown
是名字,123456434-4325234-235234-42345234
是好友ID列表,你可以解析行和单个好友,只需要保留一个字段计数并在标记化循环中调用 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
,你可以用一个简单的调用来代替calloc (strlen (p) + 1, 1)
和strcpy (pf, p);
这两个调用到 char *pf = strdup(p);
。但请注意,由于 strdup
是动态分配的,您仍应在调用后验证 if (!pf)
)
例子Use/Output
$ ./bin/strtok_csv
token: '123456789'
token: 'Jonh Brown'
token: '123456434-4325234-235234-42345234'
friends:
123456434
4325234
235234
42345234
检查一下,如果您还有其他问题,请告诉我。
我想知道如何从用逗号分隔数据的文本文件中读取数据。
例如,文本文件的第 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->friends。
这部分:123456434-4325234-235234-42345234
我把数组的friends定义为指针。因为我们不知道它的大小。我将使用动态内存分配...
如果我理解你的问题,你有一个包含用户信息和该用户的朋友的 CSV,其中朋友被编码为连字符分隔的 friend-IDs 列表作为行中的第三个字段,那么您可以使用 strtok
的 re-entrant 版本(名为 strtok_r
)的组合来分隔逗号分隔的字段,而不是在外循环中使用对 strtok
的调用来分隔连字符分隔值。
请注意,strtok_r
需要一个额外的“保存指针”作为其第三个参数,以便您可以在拥有后恢复对 strtok_r
实例的调用为替代分离目的对 strtok
或 strtok_r
的差异实例进行了中间调用。
鉴于您的行:
"123456789,Jonh Brown,123456434-4325234-235234-42345234"
其中123456789
是ID,Jonh Brown
是名字,123456434-4325234-235234-42345234
是好友ID列表,你可以解析行和单个好友,只需要保留一个字段计数并在标记化循环中调用 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
,你可以用一个简单的调用来代替calloc (strlen (p) + 1, 1)
和strcpy (pf, p);
这两个调用到 char *pf = strdup(p);
。但请注意,由于 strdup
是动态分配的,您仍应在调用后验证 if (!pf)
)
例子Use/Output
$ ./bin/strtok_csv
token: '123456789'
token: 'Jonh Brown'
token: '123456434-4325234-235234-42345234'
friends:
123456434
4325234
235234
42345234
检查一下,如果您还有其他问题,请告诉我。