0

我有读取.txt文件的代码:

Pancho: Juanka,Cony

这个想法是找到字符':'并将其分开保存在字符串数组中。与Juankaand相同,Cony但相反,它将在找到','and时出现'\0'

4

1 回答 1

0

虽然strtok会解决这个问题,但我相信它不会是一个非常可维护的解决方案。我打算指出一些使用的问题strtok,以及这些问题的解决方案。


问题#1:由于隐藏状态,strtok不可重入非线程安全的;如果您尝试同时标记两个字符串(例如交织函数调用序列或使用多个线程),您将遇到问题。

解决方案#1: strchr并且strcspn可以用来解决这个问题。我已经展示了使用 ; 阅读其他答案1 、 2 中strcspn能力;这些可以很容易地strchr改用,或使用 . 以外的字符'\n'


问题 #2: strtokstrchr并且strcspn都对需要中间数组存在的字符串进行操作。您正在从文件中读取;如果您不需要该中间数组,因为您可以将字段直接读入其对应的数组中,那么消除它们可能会公开更高级的优化和更清洁、更可维护的代码。

解决方案#2:以下代码演示了使用.fscanf

#include <stdio.h>

#define WIDTH_STR(width) #width
#define FIXED_FIELD(width) "%" WIDTH_STR(width)
#define TERMINAL(set) "[^" set "]%*1[" set "] "

#define W 1024
int parse(FILE *f) {
    char x[W+1], y[W+1], z[W+1];
    if (fscanf(f, FIXED_FIELD(W) TERMINAL(":"),  x) <= 0) { return EOF; }
    if (fscanf(f, FIXED_FIELD(W) TERMINAL(","),  y) <= 0) { return EOF; }
    if (fscanf(f, FIXED_FIELD(W) TERMINAL("\n"), z) <= 0) { return EOF; }
    printf("<%s>\n", x);
    printf("<%s>\n", y);
    printf("<%s>\n", z);
    return 0;
}

int main(void) {
    printf("parse returned: %d\n", parse(stdin));
}

问题 3:当您假设字段是固定宽度时,上述所有解决方案都达到了最佳最优性(在可维护性/复杂性和计算效率方面)。一旦该假设变得无效,使用一次读取和解析一个字节就更有意义fgetc了,根据需要重新分配以适应可变参数字段

解决方案#3:我在另一个答案中展示了读取可变长度单词的能力,这很容易适应读取单个标记并将其解析为单独的动态分配。这可能会遭受代价高昂的重新分配的缺点,需要允许您的用户输入巨大的(数兆字节)字段值,这些字段值通常不支持作为具有自动存储持续时间的固定宽度数组。

于 2017-06-04T05:08:14.757 回答