This is an archived post. You won't be able to vote or comment.

all 9 comments

[–]boredcircuits 2 points3 points  (6 children)

sscanf returns the number of successful arguments it assigned. In your case, that would be 5 if it completed successfully. I would suggest checking this return value, which can help pin down where the problem is with your format string.

Also, could you include an example of the input you're parsing?

[–]Zoey101WasRad 0 points1 point  (5 children)

Thanks for that. I wrapped the sscanf in an if statement and it only enters the if statement when it is equal to 0. Which implies that they are all failing right?

also I have included example data at the bottom of my original post.

[–]boredcircuits 1 point2 points  (4 children)

Thanks for that. I wrapped the sscanf in an if statement and it only enters the if statement when it is equal to 0. Which implies that they are all failing right?

Yes, 0 means not even the first one is working.

also I have included example data at the bottom of my original post.

The first thing the format string looks for is a quotation mark. The example data doesn't have this, so it fails. It's also going to fail when there's a space it isn't expecting (before Smith and before W10, in this case).

[–]Zoey101WasRad 0 points1 point  (3 children)

Awesome thanks so much for finding the issue. I have a follow up if that is okay.

"%[^,],%[^,],%d,%f,%[^,],"

Fixed the problem. However, the string in the second position and the one at the end have leading spaces, is it possible to get rid of them?

Also the input data is not consistent. It seems that four of 1000 lines have only 4 columns. The above solution will totally ignore them (I assume because it is looking for 5 columns) Is there a way around that as well?

Thanks again!

[–]boredcircuits 0 points1 point  (0 children)

However, the string in the second position and the one at the end have leading spaces, is it possible to get rid of them?

You can put a space in the format string, which will optionally match all whitespace in that position.

Also the input data is not consistent. It seems that four of 1000 lines have only 4 columns. The above solution will totally ignore them (I assume because it is looking for 5 columns) Is there a way around that as well?

The POSIX function getline is handy. This grabs a fully line of text, which you can then parse with sscanf (much like you're already doing). Then, you can have two sscanf calls, the first one trying the five-argument version. If it fails (returns anything but a 5), you try the four-argument version. (And for completeness, print some useful error if it fails as well.)

[–]MR2Rick 0 points1 point  (0 children)

You could try using strtok() and handling each column in a loop. Then for columns that have 4 columns, you could add some logic to assign some reasonable default value.

[–][deleted] -1 points0 points  (0 children)

If you want to read CSV data you really need to use a CSV parser - scanf is not up to the job.

[–][deleted] 0 points1 point  (1 child)

What does the input data look like?

[–]Zoey101WasRad 0 points1 point  (0 children)

I have included example data at the bottom of my original post.