gpt4 book ai didi

c - 读取每行两个单词的文件并在 C 中以有效的方式保存单词

转载 作者:太空宇宙 更新时间:2023-11-04 04:23:56 25 4
gpt4 key购买 nike

我有一个文本文件,每行都有一对单词,我用它来阅读它们:

for (i=0, j=0; (c=fgetc(fp))!=EOF; i++){
if (c == ' '){
pares[j].par1[i] = '\0';

for (i=0; (c=fgetc(fp))!= '\n'; i++){
pares[j].par2[i] = c;
}
j++;
i= -1;
}
else{
pares[j].par1[i]=c;
}
}

n_pares = j;
fclose(fp);

“pares”是一个包含行的第一个词 (par1) 和第二个词 (par2) 的结构,我知道我不需要这样做。但我不知道这是否是最有效的方法。因为在 python 中我只会使用函数 split() 而我不需要执行 for 循环。谁能告诉我是否有更有效的方法?

最佳答案

与逐个字符读取相比,分配一个大的行缓冲区一次,将行读入该缓冲区,然后将其处理成大小更合适的片段通常更有效。

char line[1024];
while(fgets(line, 1024, fp) != NULL) {
...now process line...
}

在 C 中拆分一行比在高级语言中要困难一些。标准函数是strtok (字符串标记),使用起来有点有趣。

    const char sep[] = " \t\n";

for(
char *token = strtok( line, sep );
token != NULL;
token = strtok( NULL, sep )
) {
printf("%s ", token);
}

printf("\n");

发生的事情是 strtok 在查看字符串时记住它的位置,但它一次只能对一个字符串执行此操作。在字符串中传递它会将其重置回开头。所以 strtok( line, sep )line 上启动进程,并且 strtok( NULL, sep )line 上获取下一个标记 直到没有剩余。

此全局状态由对 strtok 的所有调用共享,因此在使用 strtok 时调用另一个函数甚至不安全,该函数也可能调用 strtok 并重置状态。

非标strtok_r更安全,它使用一个变量来记住它在哪里。 strsep有更好的接口(interface),但它也是非标准的。

这些都是通过修改正在迭代的字符串来工作的。 token 只是指向 line 的指针。例如,如果我们有这样的东西:

// Let's say line is pointing at memory location 1000
// 'U' is at 1000, 'p' is at 1001, ' ' is at 1002, etc...
line = 1000
|
v
"Up down\n\0"

第一次调用 char *token = strtok( line, sep ); 结果。

line = 1000
|
v
"Up\0down\n\0"
^
|
token = 1000

token 指向字符串的开头,但请注意空格已替换为空字节。这使您可以将 token 用作字符串 "Up" 而无需分配新内存。注意字符串被修改了!

第二个 token = strtok( NULL, sep ) 导致 token 移动。

line = 1000
|
v
"Up\0down\0\0"
^
|
token = 1003

末尾的换行符已替换为空字节。现在 token 包含字符串 "down",但它只是指向与 line 共享的内存。如果你打印 line,你会得到 "Up"

在最后的 token = strtok( NULL, sep ) 中,token 将被设置为 NULL,因为不再有非分隔符。 保持修改状态。

line = 1000
|
v
"Up\0down\0\0"

token = NULL

要点是,您不能存储 token,因为它指向 line 并且 line 将更改循环的下一次迭代。您必须复制 token 指向的字符串,如 strdup .这是非常有效的内存,它避免了不必要的内存分配和复制,但如果您来自高级语言,可能会有点难以理解。

关于c - 读取每行两个单词的文件并在 C 中以有效的方式保存单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43529459/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com