我的代码读取.txt
文件:
Pancho: Juanka,Cony
我们的想法是找到角色':'
并将其保存在一个字符串数组中。与Juanka
和Cony
相同,但相反,它会在找到','
和'\0'
时发生。
答案 0 :(得分:0)
虽然strtok
可以解决这个问题,但我相信它不会是一个非常可维护的解决方案。我打算指出使用strtok
的一些问题,以及这些问题的解决方案。
问题#1 :由于隐藏状态,strtok
不可重入和非线程安全;如果你试图同时标记两个字符串(例如交织函数调用序列,或使用多个线程),你将遇到问题。
可以使用解决方案#1: strchr
和strcspn
来解决此问题。我已经证明能够使用strcspn
在其他答案 1,2 中读取行;这些可以很容易地适应使用strchr
代替,或使用'\n'
以外的字符。
问题#2: strtok
,strchr
和strcspn
都对需要中间数组的字符串进行操作。你是从一个文件中读取的;如果你不需要那个中间数组,因为你可以直接将字段读入相应的数组,那么消除它们可能会暴露出更高级的优化和更清晰,更易维护的代码。
解决方案#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中读取可变长度的单词,这些单词很容易适应读取和解析单个标记到单独的动态分配中。这可能会遇到必须进行昂贵的重新分配以使用户输入巨大(多兆字节)字段值的缺点,这些字段值通常不会被支持为具有自动存储持续时间的固定宽度数组。