Reputation: 172
I'm parsing some CSV data in C for the purposes of a Ruby extension. In order to pull out the data from each row I'm using sscanf as follows:
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, ®ion_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
Running it produces this:
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
Note the null strings. Basically, it seems like sscanf is tripping on these for some reason. I can't figure out why even having read the docs thoroughly. Any ideas?
Upvotes: 0
Views: 3861
Reputation: 67
Allocating memory on the stack is the simple way. Example:
char issued[1024] = {0};
char bid[1024] = {0};
By the way, "Allocating memory on the stack" really just means taking the current position of the stack pointer, assigning it to the variable name and then incrementing the stack pointer by the size of the type of the variable. It's an extremely quick operation compared with allocating memory on the heap with malloc and friends. Unlike with malloc however you lose any stack allocated memory once you pop your current stack frame (i.e. execution reaches the end of the current function).
Upvotes: 2
Reputation: 13872
I agree with Thanatos. As a first start you need to allocate memory for issued and bid, you might do:
char issued[1024]; char bid[1024];
Upvotes: 0
Reputation: 2725
%s
matches non-whitespace characters. What you probably want is %[^,]255
which will match every character other than ,
instead of %s
. The 255, which is optional, specifies the field width that you're expecting for that field.
Upvotes: 1
Reputation: 44256
Your character pointers are unitialized, and point to a random segment of memory. You must allocate a buffer for sscanf() to write to, and it must be big enough. (You're lucky that didn't segfault.) That second part is the hard part -- scanf() might not be the right tool for the job here.
Upvotes: 2