简体   繁体   中英

C fgets semantic error

I'm new in the C world, and I've a problem with fgets() function. I googled almost 2 hours my error, and found different solutions but no one worked.

My class is too big for just show every parts of it, but let me show you the problematic part:

//... kivansag is a struct(!)
if(check == 1){
        char name;
        printf("Please give me your nickname!\n");
        scanf("%s", &name);
        strcpy(kivansag.name,&name);

        char city;
        printf("Please give me your city!\n");
        scanf("%s", &city);
        strcpy(kivansag.city,&city);

        char *address = malloc(100);
        printf("Please give me your address!\n");           
        fgets(address,100,stdin);

        if((strlen(address)>0) && address[strlen(address)-1] == '\n'){
            address[strlen(address)-1] = '\0';
        }

        strcpy(kivansag.address,address);
        free(address);
}//...

The problem is: Every time I run this code, the running server is skipping fgets() after it wrote out "give me your address", and do the following function.

May I get any suggestions?

UPDATED:

Now I have only this:

        printf("Please give me your address!\n");           
        fgets(kivansag.address,sizeof(kivansag.address),stdin);

        if((strlen(kivansag.address)>0) && kivansag.address[strlen(kivansag.address)-1] == '\n'){
            kivansag.address[strlen(kivansag.address)-1] = '\0';
        }

the struct seems like this:

struct Kivansag{
  //...
  char address[100];
};

And yeah, still skipping my part... I tried to use fflush(stdin) too, to make sure everything is clear, but not worked.

 scanf("%s", &name);      //you cant use %s to take input in a char variable
 ...
 scanf("%s", &city);

In these name and city are two char variables , not null terminated strings. Thus , using here -

strcpy(kivansag.name,&name);

leads to UB .

You can declare them as arrays -

char name[20];
char city[20];
fgets(name,20,stdin);    
...
fgets(city,20,stdin); 
strcpy(kivansag.name,name);      // note address of name is not required 
/* similarly for copying city */

So due this next fgets will also not be skipped.

And then do as you were doing .

char is just a single character, you can't use it to read a string with the %s format in scanf . You need to provide a character array. There's no need to scan into one variable and then copy into another, you can scan directly into the structure member.

scanf("%s", kivansag.name);

You can also use fgets() directly into the variable:

fgets(kivansag.address, sizeof kivansag.address, stdin);
size_t len = strlen(kivansag.address);
if((len>0) && kivansag.address[len-1] == '\n'){
    kivansag.address[len-1] = '\0';
}

See fgets doesn't work after scanf for why your program is skipping fgets and how to fix it.

these two lines are always going to produce undefined behaviour.

Undefined behaviour can result in anything, including a seg fault event

    char name;
    ....
    scanf("%s", &name);

the function scanf() always appends a NUL byte to the string that was input.

there is only one byte defined in char name .

There is no limit put on the "%s" so the user can/will always overrun that one byte buffer.

Suggest something like:

    char name[30];
    ....
    if( 1 != scanf("%29s", &name) { // handle error }

this line:

scanf("%s", &city);

left a newline in the input stream.

the following call to fgets() will see that newline, and immediately return with nothing put into the input buffer but the newline and a NUL byte

this very messy lines:

if((strlen(address)>0) && address[strlen(address)-1] == '\n'){
        address[strlen(address)-1] = '\0';
    }

may or may not find an embedded newline and overlay it with a NUL byte Suggest:

if( char* newline = strstr( address, "\n" ) )
    *newline = '\0';

There are even 'neater' ways to replace the newline in the string but this method is easy to understand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM