-1

I am using sscanf to read user input and save to several outputs. As far as my understanding goes, if I have sscanf(iput, %s %s %s %s, arr[0], arr[1], arr[2], arr[3]) I can have up to 4 items entered, but it does not require 4; meaning I could just put two and arr[2] ad arr[3] would have no value. However, I think I am not understanding something since later when I check the values of arr[2]/arr[3] they are not null, when I thought strings were just initialized with \0. Look at my code please and tell me what the if statement should be checking for I guess.

printf("Enter a command: ");
        char input[20];
        char line[5][20];
        fgets(input, 20, stdin);
        sscanf(input, "%s %s %s %s %s", line[0], line[1], line[2], line[3], line[4]);
....

else {
            int status;
            if(line[4] != NULL) {
                char *args[6];
                args[0] = line[0];
                args[1] = line[1];  
                args[2] = line[2];
                args[3] = line[3];
                args[4] = line[4]; 
                args[5] = NULL;
            if ( fork() == 0 ) {
                execv( args[0], args ); // child: call execv with the path and the args
            }
            else {
                wait( &status );  
            }    
  • 1
    Please post a [mre]. scanf is not safe for use due to potential buffer overflow. Use `fgets()` instead. – Allan Wind Sep 26 '21 at 23:41
  • Also, I don't think your code even compiles. scanf("%s ..." expects a char * but you pass it a char (`line[0]`). – Allan Wind Sep 26 '21 at 23:46
  • 1
    if you only pass two percent signs in the format string then scanf thinks you are only passing two variables. If it doesn't know about the last two it isn't going to fill them with anything - not even NULL. But that's not all: if you declare `char line[5][20];` then line[x] will always have a value and will never be NULL because you have actually already allocated that memory. If you want some of them to be NULL you need to declare it as `char *line[5] = {0};` and then allocate memory for all the pointers that you want to be non-NULL. – Jerry Jeremiah Sep 26 '21 at 23:48
  • `if(line[4] != NULL)` This can never be true. `line[4]` is an array which can never decay to `NULL` pointer. – Gerhardh Sep 27 '21 at 07:12

2 Answers2

0

scanf will attempt to get everything you asked for. You ask for five, it tries to get five.

sscanf(input, "%19s %19s %19s %19s %19s", line[0], line[1], line[2], line[3], line[4]);

Without the specification, it will take as many chars as the user is inclined to submit, thus resulting in a buffer overflow. Bad idea.

I would accept one argument at a time, or take it all as one lump.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
0

Using the comment Jerry Jeremiah said, instead of changing the declaration to a pointer, I changed the line[x] in the if statement to a pointer and checked for NULL.