0

为了 Ruby 扩展,我正在用 C 解析一些 CSV 数据。为了从每一行中提取数据,我使用 sscanf 如下:

  char* line = RSTRING_PTR(arg);
  double price;
  double volume_remaining;
  unsigned int type_id, range, order_id, volume_entered, minimum_volume, duration, station_id, region_id, solar_system_id, jumps;
  char* issued;
  char* bid;
  printf("I got %s\n",line);
  int res = sscanf(line, "%lf,%lf,%u,%u,%u,%u,%u,%s,%s,%u,%u,%u,%u,%u", &price, &volume_remaining, &type_id, &range, &order_id, &volume_entered, &minimum_volume, bid, issued, &duration, &station_id, &region_id, &solar_system_id, &jumps);
  printf("I matched %d values\n", res);
  printf("I have price %f, vol_rem %f, type_id %d, range %d, order_id %d, vol_ent %d, min_vol %d, issued %s, bid %s, duration %d, station_id %d, region_id %d, solar_system_id %d, jumps %d, source %s \n",price, volume_remaining, type_id, range, order_id, volume_entered, minimum_volume, issued, bid, duration, station_id, region_id, solar_system_id, jumps, source); // and hash build follows below

运行它会产生这个:

I got 728499.93,437.0,2032,32767,1132932560,588,1,False,2009-05-24 19:52:08.000,90,60003760,10000002,30000142,0
I matched 7 values
I have price 728499.930000, vol_rem 437.000000, type_id 2032, range 32767, order_id 1132932560, vol_ent 588, min_vol 1, issued (null), bid (null), duration -1210229476, station_id 3001, region_id 3001, solar_system_id 1, jumps -1210299816

注意空字符串。基本上,似乎 sscanf 出于某种原因而绊倒了这些。我什至无法弄清楚为什么要彻底阅读文档。有任何想法吗?

4

4 回答 4

2

您的字符指针是未初始化的,并指向随机的内存段。您必须为 sscanf() 分配一个要写入的缓冲区,并且它必须足够大。(你很幸运没有出现段错误。)第二部分是困难的部分—— scanf() 可能不是这里工作的正确工具。

于 2009-07-01T00:23:42.873 回答
2

在堆栈上分配内存是一种简单的方法。例子:

char issued[1024] = {0};
char bid[1024] = {0};

顺便说一句,“在堆栈上分配内存”实际上只是指获取堆栈指针的当前位置,将其分配给变量名,然后将堆栈指针增加变量类型的大小。与使用 malloc 和朋友在堆上分配内存相比,这是一个极其快速的操作。与 malloc 不同的是,一旦您弹出当前堆栈帧(即执行到达当前函数的末尾),您将丢失任何堆栈分配的内存。

于 2013-01-10T13:53:55.673 回答
1

%s匹配非空白字符。您可能想要的是%[^,]255匹配每个字符,而不是%s. 255 是可选的,它指定您期望该字段的字段宽度。

于 2009-07-01T00:39:33.013 回答
0

我同意塔纳托斯的观点。作为第一个开始,您需要为已发布和出价分配内存,您可以这样做:

字符发出[1024];字符出价[1024];

于 2009-07-01T00:39:37.613 回答