Search code examples
cstringinput

String manipulation and conversion


For an exercise, I can take two integers or two strings. If I want integers as input, I need to convert them to strings or if I take strings as input, I need to convert the strings to integers. When i want to input two strings at once, somehow, they are being concatenated. If I take integers, when I want to convert using snprintf, the strings are being concatenated again!

When I take strings as input:

#include <stdio.h>
int main(){

    char n[5],m[5];
    scanf("%s %s",n,m);
    printf("%s %s\n",n,m);
}

The input is 12345 56789

but the output is 1234556789 12346

the scanner thinks that "12345 56789" is a whole string.

How is this happening? Didn't I specify that n can only hold 5 char? If I reduce n[5] to n[1] the output is 156789 56789

When I take integers as input and try to convert using snprintf:

#include <stdio.h>
#include <stdlib.h>
int main(){
    
    int g,w,cnt=0;
    
    scanf("%d %d",&g,&w);
    
    char n[5], m[5];
    snprintf(n,6,"%d",g);
    snprintf(m,6,"%d",w);
    printf("%s\n",n);
    printf("%s\n",m);
}

If I input 12345 67894 Output is 1234567894 67894.

Same problem as before. What can I do to fix this issue?


Solution

  • There are several issues here:

    1. In order to store a 5 character string, you need a char array of at least 6 elements, because you must keep 1 additional char for the zero termination.

      Therefore n and m should be:

      char n[6],m[6];
      
    2. As mentioned by @TedLyngmo using scanf for strings the way you did is unsafe (even after fixing the array sizes), and invokes undefined-behavior if the user enters more than 5 characters per string (because of writing out-of-bounds).

      In order to fix it, you should use scanf with a width specifier:

      If width specifier is used, matches up to width or until the first whitespace character, whichever appears first.

      This is done in the following way:

      //------v---v--------
      scanf("%5s %5s",n,m);
      
    3. Good practice dictates always checking the return value from scanf to make sure it succeeded. It returns:

      Number of receiving arguments successfully assigned

      In your case it should be 2 upon success.

    A complete fixed example for your first snippet:

    #include <stdio.h>
    #include <cstdlib>
    
    int main() {
    
        char n[6], m[6];
        if (scanf("%5s %5s", n, m) != 2) {
            // Handle error ...
            return EXIT_FAILURE;
        }
        printf("%s %s\n", n, m);
    }
    

    Regarding your second snippet the relevant problematic issues are 1 and 3 above (char array sizes, and checking the return value from scanf).