如何将文本文件中的行的子字符串保存到字符串数组中?

时间:2017-06-04 03:42:14

标签: c arrays string string.h

我的代码读取.txt文件:

Pancho: Juanka,Cony

我们的想法是找到角色':'并将其保存在一个字符串数组中。与JuankaCony相同,但相反,它会在找到',''\0'时发生。

1 个答案:

答案 0 :(得分:0)

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

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

可以使用解决方案#1: strchrstrcspn来解决此问题。我已经证明能够使用strcspn在其他答案 12 中读取行;这些可以很容易地适应使用strchr代替,或使用'\n'以外的字符。

问题#2: strtokstrchrstrcspn都对需要中间数组的字符串进行操作。你是从一个文件中读取的;如果你不需要那个中间数组,因为你可以直接将字段读入相应的数组,那么消除它们可能会暴露出更高级的优化和更清晰,更易维护的代码。

解决方案#2:以下代码demonstrates使用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:我已经证明了能够在another answer中读取可变长度的单词,这些单词很容易适应读取和解析单个标记到单独的动态分配中。这可能会遇到必须进行昂贵的重新分配以使用户输入巨大(多兆字节)字段值的缺点,这些字段值通常不会被支持为具有自动存储持续时间的固定宽度数组。