0

I have a problem with sscanf function...

Here is my code :

char str[]="Andrew;;;3454";
char name[20] = {0};
char city[20] = {0};
char age[5] = {0};
char hasDegree[20] = {0};

sscanf(str,"%[^;];%[^;];%[^;];%[^;]",name,city,age,hasDegree);

printf("%s is %s Years Old and live in %s at %s degrees",name,age,city,hasDegree);

The output : Andrew is Years Old and live in at degrees

As you can see, "Andrew" is printed but not "3454" (because there are 2 blank before?)

How to solve it please?

I have declared everything in char voluntarily :)

Thank you !

Esref
  • 45
  • 5
  • 2
    Don't use any version of `scanf()` if you need any robustness parsing data. – Andrew Henle Jan 08 '21 at 15:27
  • What do you suggest I use now? I heard about strtok – Esref Jan 08 '21 at 15:33
  • See [here](https://stackoverflow.com/questions/2430303/), [here](https://stackoverflow.com/questions/35178520/), and [here](https://stackoverflow.com/questions/58403537/). – Steve Summit Jan 08 '21 at 15:46
  • I used strsep and when I print, it works ! But how to save each separated string in variables? (name, city etc..) I would like to use a typedef struct like : typedef struct identity{char name[20].......}identity; – Esref Jan 08 '21 at 16:49

1 Answers1

0

The [ conversion matches a non-empty set of characters. The empty fields cause the conversion to fail before reading reaches the 3454 field.

In general, I find the scanf family of functions hard to use, especially when error recovery is required (e.g., here you could check the return value for the number of fields successfully read, but the recovery would be more complicated than just reading them one by one to begin with). I would suggest strtok or strsep (if available) for parsing fields. Or if you have other reasons to use scanf, read one field at a time and then move the read position past the next ;.

Arkku
  • 41,011
  • 10
  • 62
  • 84
  • Ok thank you, but the strtok will ignore the consecutive delimiters, how to solve it? – Esref Jan 08 '21 at 16:03
  • 1
    @Esref `strsep` is a non-standard (but widely available) replacement that supports empty fields. But you could just parse it manually very easily, it's just a matter of find the next `;` character (either manually or with `strchr`). If the string is editable (as it is your example), you can easily replace the next `;` with `\0`, copy the string, then advance the read position to one past the terminator (if it was a `;`, if it was the original `\0` you are done). – Arkku Jan 08 '21 at 16:09