Home > Enterprise >  String Unexpected Behavior in C
String Unexpected Behavior in C

Time:07-23

I was writing a simple program to read a string and then print it.

#include<stdio.h>

// void printString(char *str){
//     while(*str!='\0'){
//         printf("%c",*str);
//         str  ;
//     }
//     printf("\n");
// }

int main(){
    char str[50];
    printf("Enter Your Name:-");
    scanf("%s",&str);       // scanf adds '\0' automatically at the end.
    char *ptr = str;
    // printString(ptr);
    printf("Your Name is %s%s",ptr);
    return 0;
}

I wrote the above code. At first I didn't know that scanf stops when encounters a space. So I thought that I need to have two %s for printing two words but when I got to know the former part about scanf. I understood the problem but in the process, I encountered another problem which I think is unexpected behavior.

OUTPUT:-

Enter Your Name:-Rachit Mittal

Your Name is Rachit Mittal

This Output, from my understanding is unexpected. If scanf only reads till it encounter space or new line then string contains only "RACHIT" So in the output screen even after using double %s, It should only print "Rachit" instead of "Rachit Mittal"

I wanna ask why is this so? Is this unexpected behavior because of double %s or something else?

CodePudding user response:

You are invoking undefined behavior by not passing enough arguments to printf. %s%s contains two format specifiers, so printf expects two string arguments to be passed, but you only gave one. In this case, the result could be anything.

Consider enabling warnings to help diagnose these errors (e.g. compiling with -Wall).

CodePudding user response:

You have two %s in the format string, but only one additional argument. So there's no argument corresponding to the second %s. This causes undefined behavior. This means that anything can happen, so nothing should be "unexpected".

It's a bit surprising that this causes it to print the second name from the input. The register or memory location that would have contained an additional argument just happened to point to the remainder of the input buffer used by stdio. This is purely coincidence.

CodePudding user response:

For starters the second argument expression in this call of scanf

scanf("%s",&str);

is incorrect. The type of the expression &str is char ( * )[50] while the conversion specifier %s expects an argument of the type char *. You have to write

scanf( "%s", str );

As for your problem then according to the C Standard (7.21.6.1 The fprintf function)

2 The fprintf function writes output to the stream pointed to by stream, under control of the string pointed to by format that specifies how subsequent arguments are converted for output. If there are insufficient arguments for the format, the behavior is undefined. If the format is exhausted while arguments remain, the excess arguments are evaluated (as always) but are otherwise ignored. The fprintf function returns when the end of the format string is encountered.

You could write to read several words

scanf( "I[^\n]", str );
  • Related