【问题标题】:c fscanf storing stringsc fscanf 存储字符串
【发布时间】:2019-11-30 19:49:34
【问题描述】:

我正在使用 fscanf 读取每行具有这种格式的文件:

//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_DMS|SOURCE_LAT_DEC|SOURCE_LONG_DEC|ELEV_IN_M|ELEV_IN_FT|MAP_NAME|DATE_CREATED|DATE_EDITED

这里是文件的第一行,例如:

//913064|Oso Spring|Spring|NM|35|Rio Arriba|039|365418N|1061159W|36.904945|-106.1998199|||||2863|9393|Bighorn Peak|12/01/1991|04/19/2011

我的代码是这样的:

int id, state_num, county_num, elev_m, elev_f;
float lat_dec, lon_dec;
char* name[25];
char* class[25];
char* state[25];
char* county[25];
char* lat[25];
char* lon[25];
char* s_lat_dms[25];
char* s_lon_dms[25];
char* s_lat_dec[25];
char* s_lon_dec[25];
char* map_name[25];
char* date_created[25];
char* date_edited[25];

fscanf(data, "%d|%[^|]s|%s|%s|%d|%s|%d|%s|%s|%f|%f|%s|%s|%s|%s|%d|%d|%s|%s|%s", &id, name,
class, state, &state_num, county, &county_num, lat, lon, &lat_dec,
           &lon_dec, s_lat_dms, s_lon_dms, s_lat_dec, s_lon_dec, &elev_m, &elev_f, map_name,
date_created, date_edited);
    printf("id:%d \nname:%s \nclass:%s \nstate:%s \nstate_num:%d \n", id, name, class, state,
state_num);

但是当我在命令行上运行它时,它会打印出这个:

id:913064

名称:奥索泉

类:�&6+�

状态:

state_num:1178

为什么不能在 char* 类数组中正确存储数据? 有一些特定的代码需要保留,比如第一个字符串值需要能够保留空格,所以我添加了“[^|]”,但是一旦我这样做了,它就开始输入无意义的字符班级。我已经广泛研究了 fscanf 但找不到如何正确地做我想做的事情。有人可以帮我妥善组织一下,填补我似乎无法填补的知识空白吗?

【问题讨论】:

  • 不应该 char* name[25];char name[25]; 等吗?确保您也使用%25s 限制输入长度。另请注意,%s 扫描的 Bighorn Peak 将停在空格处,留下 Peak 由下一个格式说明符扫描。
  • 您没有要求另一种方法来执行此操作,而是一次将整行读取到一个大缓冲区中,然后使用 strtok()'|' 分隔符上将字符串分开与scanf 相关的角色可能不会那么令人抓狂
  • 使用strtok 是处理逗号或制表符分隔文本等数据的常用方法,但它的缺点是连续分隔符(如|||||)被视为单个 分隔符,而不是留下“空”数据字段。如果您有strsep,它将单独处理每个|
  • @WeatherVane 是的,当然,尽管我认为 strtok 的错误答案仍然是对 scanf 的改进:-)
  • @SteveFriedl 我同意:我从不喜欢使用scanf family 过滤除空格以外的任何分隔符。

标签: c string scanf


【解决方案1】:

没有格式说明符%[...]s。只有%[...]。删除 s,因为它会导致 fscanf 函数在输入中查找文字 s

如前所述,您有指针数组,而不是字符数组。这意味着例如state 作为参数将衰减为指向其第一个元素的指针,而该指针又是一个指针,并且它将具有 char ** 类型,这对于 %[%s 格式都是不正确的。

调用printf时指针数组的问题也会导致问题。

一个好的编译器会警告不匹配的类型和格式说明符。如果您没有,请尝试启用更多警告(例如使用 -Wall -Wextra 与 GCC 或 Clang)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    相关资源
    最近更新 更多