sscanf%s,其中字符串可以为空

时间:2019-12-03 22:07:52

标签: c formatting scanf

我正在使用sscanf来读取具有非常相似的数据集但可能包含或可能不包含某些数据点的文件行。这是数据的格式: FEATURE_ID | FEATURE_NAME | FEATURE_CLASS | STATE_ALPHA | STATE_NUMERIC | COUNTY_NAME | COUNTY_NUMERIC | PRIMARY_LAT_DMS | PRIM_LONG_DMS | PRIM_LAT_DEC | PRIM_LONG_DEC | SOURCE_LAT_DMS | SOURCE_LONG_D_P

看起来像这样填写: 924821 |原油和炼油厂编号1 |弹簧| NM | 35 | Hidalgo | 023 | 313030N | 1082532W | 31.5084388 | -108.4255951 | ||| | 1382 | 4534 | U巴里奇| 03/01 / 1994 |

或类似,取决于这些数据点是否存在: 924855 |棉木洗涤|流| NM | 35 |圣胡安| 045 | 364554N | 1090003W | 36.7649994 | -109.0009304 | 364623N | 1090126W | 36.7730556 | -109.0238889 | 1654 | 5426 | Beclabito | 03/01 / 1994 |

我的问题出在“ ||||”这是一组分隔符,用于分隔可能存在或可能不存在的数据点。我正在尝试格式化sscanf,以将这些数据点值存储为字符串,无论数据点是否实际存在,但是使用格式说明符“ [^ |]”和“%s”不起作用。我该如何进行条件阅读?

这是我的sscanf:

sscanf(curr, "%d|%[^|]|%[^|]|%[^|]|%d|%[^|]|%d|%[^|]|%[^|]|%f|%f|||||%d|%d|%[^|]|%[^|]|%[^|\n]", &id, name, class, state, &state_num, county, &county_num, lat, lon, &lat_dec, &lon_dec, &elev_m, &elev_f, map_name, date_created, date_edited);

我目前只是忽略这些值,并且好像它们不存在一样工作。我该如何考虑这些?

编辑/澄清: 我需要像%s这样的sscanf格式说明符,该格式说明符不扫描任何内容。例如,我可以执行sscanf(“ one | 2”,“%s |%d”,str,num),但如果是sscanf(“ | 2”,“%s |%d”,str,num)它会引发错误,但我需要它在str中存储NULL。

2 个答案:

答案 0 :(得分:0)

您可以将数据存储在某个临时缓冲区中。

// non interesting parts omitted with three dots...
char trash[256];
sscanf("...|%255s|%255s|%255s|%255s|", ... &trash, &trash, &trash, &trash, ....);

或者只是您可以禁止使用*字符分配数据:

sscanf(curr, "%d|%[^|]|%[^|]|%[^|]|%d|%[^|]|%d|%[^|]|%[^|]|%f|%f|%*[^|]|%*[^|]|%*[^|]|%*[^|]|%d|%d|%[^|]|%[^|]|%[^|\n]", &id, name, class, state, &state_num, county, &county_num, lat, lon, &lat_dec, &lon_dec, &elev_m, &elev_f, map_name, date_created, date_edited);

例如,有关cppreference/fscanf的scanf系列功能的更多信息。

答案 1 :(得分:0)

至少不能简单地用sscanf做到这一点,因为所有scanf变体都需要数据转换以匹配至少一个字符。

如果您拥有strsep(可用于glibc和大多数BSD C库实现),则可以使用它来将字符串分成多个字段。 (请注意,strsepstrtok一样,不会复制字段。有时这很方便,但是在其他情况下,您将需要复制标记化的字段或数据缓冲区,或同时复制两者。)< / p>

如果您只有标准的C库函数,请依次使用strchrstrpbrk查找每个分隔符,然后用NUL覆盖分隔符(strsep会这样做)或复制标记化字段。