Audai haj Yahya
Audai haj Yahya

Reputation: 35

sscanf function does not read the format as required

Im trying to use sscanf function in C but its not reading the format is its required, I've readed the documentation of the function and followed the examples but its still not working out well for me thus i would like to have some advises..

int main() {

  long int id;
  float grade,age;
  char name[40],city[40],country[40],line[100]="388891477\tItzel\tGardner\t21\t6\tIran\tTehran";

  int read_items = sscanf(line,"%ld %*[\t] %[a-zA-Z -] %*[\t] %f %*[\t] %f %*[\t] %[a-zA-Z -] %*[\t] %[a-zA-Z -]",
        &id,name,&age,&grade,country,city);

  printf("readed line is: %ld %s %f %f %s %s. sscanf() read %d items\n",id,name,grade,age,country,city,read_items);

}

current output:

readed line is: 3888914775  0.000000 0.000000  @�'�. sscanf() read 1 items

expected output:

readed line is: 3888914775 Itzel Gardner  21.000000 26.000000 Iran Tehran. sscanf() read 6 items

ANOTHER EDIT:

question requirements was to add the tabs so if there was a space in the input it should return that this input is incorrect and shouldn't read it thats the main reason i added the tabs so it could only read inputs that have tabs in it , so for example if input between id and name was only 1 space it shouldn't read it.. sorry for confusing everyone

so in the line[100]="3888914775 Itzel Gardner 21 26 Iran Tehran";

input the sepration input between each one can only be tab nothing else( not one space or two.. )

CORRECT INPUT EXAMPLE:

line[100]="388891477\tItzel\tGardner\t21\t6\tIran\tTehran";

Upvotes: 3

Views: 284

Answers (4)

chux
chux

Reputation: 153338

Use string literal concatenation to help clearly solve this.

To scan, and not save, a '\t' and only 1, use "%*1[\t]".

Scan safely - use width limits when saving strings. E.g "%39[^\t]"

Untested code:

#define FTAB "%*1[\t]"  
#define FID  FTAB "%ld"  
#define FTXT FTAB "%39[^\t]"
#define FNUM FTAB "%f"

long int id;
float grade,age;
char name[40],city[40],country[40];
char line[100]="388891477\tItzel\tGardner\t21\t6\tIran\tTehran";

int read_items = sscanf(line, FID FTXT FNUM FNUM FTXT FTXT,
    &id, name, &age, &grade, country, city);

printf("read %d items\n", read_items);
if (read_itmes == 6) {
  printf("readed line is: %ld %s %f %f %s %s\n", 
      id, name, grade, age, country, city);
}

Upvotes: 1

Anup Agrawal
Anup Agrawal

Reputation: 85

  • You are writing your name with space . Because of that , it will be consider as a next input and accepted into next datatype which is in your code as ::

In char array line , Itzel Gardner this is have space between each other.

  • you don't need to give [A -Z a-z] for storing string into char array , you just use %s for that .

in sscanf , you should use %s instead of [A -Z a-z] . - You don't need to give "\t" in in sscanf func.

this code has a solution

int main() 
{

        long int id;
        float grade,age;
        char name[40],city[40],country[40],line[100]="3888914775 Itzel_Gardean 21 26 Iran Tehran";

        int read_items = sscanf(line,"%ld %s %f %f  %s %s",&id,name,&age,&grade,country,city);

        printf("readed line is: %ld %s %f %f %s %s. sscanf() read %d items\n",id,name,grade,age,country,city,read_items);

}

Upvotes: 0

VJAYSLN
VJAYSLN

Reputation: 473

int main() {

  long int id;
  float grade,age;
  char name[40],city[40],country[40],line[100]="3888914775 Itzel Gardner 21 26 Iran Tehran";

  int read_items = sscanf(line,"%ld %[a-zA-Z- ] %f %f %[a-zA-Z-] %[a-zA-Z-]",
        &id,name,&age,&grade,country,city);

printf("readed line is: %ld %s %f %f %s %s. sscanf() read %d items\n",id,name,grade,age,country,city,read_items);

}

While removing %*[\t] from sscanf, your program will works fine. And also you don't want to change your datatype from float into int. Hope it will helps : )

Upvotes: 1

Fred Larson
Fred Larson

Reputation: 62053

As I see it, your code has a few issues.

First, the %*[\t] specifiers are interfering and should not be necessary. A space between specifiers in sscanf will cause all whitespace to be consumed.

Second, the ID value you have may overflow a long int, so you may need to use long long instead with a %lld specifier.

Finally, there seems to be some confusion about whether spaces or tabs separate fields. Spaces are valid values for all your string fields, but also given between field. Your comments mention tabs, but I don't see any in your line string. If you use tabs to separate your fields things work much better, as the tab character is not part of your specifier sets.

Here is my update of your code correcting all the above:

#include <stdio.h>

int main() {

  long long id;
  float grade,age;
  char name[40],city[40],country[40],line[100]="3888914775\tItzel Gardner\t21\t26\tIran\tTehran";

  int read_items = sscanf(line,"%lld %[a-zA-Z -] %f %f %[a-zA-Z -] %[a-zA-Z -]",
        &id,name,&age,&grade,country,city);

  printf("readed line is: %lld %s %f %f %s %s. sscanf() read %d items\n",id,name,grade,age,country,city,read_items);

}

Output:

readed line is: 3888914775 Itzel Gardner 26.000000 21.000000 Iran Tehran. sscanf() read 6 items

Upvotes: 1

Related Questions