cpointerscharactercompiler-warningsshort

"incompatible pointer type" compiling in C


My code

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

void getData(short int *number, char *string)
{
    printf("\nPlease enter a number greater than zero: ");
    scanf("%hd", number);

    printf("Please enter a character string: ");
    scanf("%s", string);
}

void echoPair(short int *number, char *string)
{
    printf("Number: %hd Character(s): %s\n", *number, string); 
}

int main()
{
    short int *number = 0;
    char string[32] = {0};

    printf("This program will ask you to enter a number greater than zero and \na character string with less than 32 characters \ninput.");

    getData(&number, &string);
    echoPair(&number, &string);
    return(0);
}

The code works fine, but I receive these compiler warnings

warning: passing argument 1 of ‘getData’ from incompatible pointer type
warning: passing argument 2 of ‘getData’ from incompatible pointer type
warning: passing argument 1 of ‘echoPair’ from incompatible pointer type
warning: passing argument 2 of ‘echoPair’ from incompatible pointer type

If do this

    getData(number, string);
    echoPair(number, string);

The warnings go away, but the program gets a "Segmentation fault: 11" after I enter the first number in the getData function.

Anyone know how to remove the warnings and keep the program working?

Thanks


Solution

  • There are a number of problems here.


    First, the line:

    short int *number = 0;
    

    should be:

    short int number = 0;
    

    Because you used the former, it gave you a null pointer to a short. That's not what you want since the first dereference of that beast will probably crash your code (or, worse, not crash your code but cause strange behaviour).


    Secondly, you don't need to pass in the address of strings, they automatically decay to an address, so change:

    getData (&number, &string);
    echoPair (&number, &string);
    

    to:

    getData (&number, string);
    echoPair (&number, string); // but see last point below.
    

    And, last of all, you don't need to pass in the address just to print it, you can just pass in the value, hence:

    echoPair (&number, &string);
    

    becomes:

    echoPair (number, string);
    

    As a whole, I think what you want is:

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    void getData(short int *number, char *string) {
        printf("\nPlease enter a number greater than zero: ");
        scanf("%hd", number);
    
        printf("Please enter a character string: ");
        scanf("%s", string);
    }
    
    void echoPair(short int number, char *string) {
        printf("Number: %hd Character(s): %s\n", number, string);
    }
    
    int main (void) {
        short int number = 0;
        char string[32] = {0};
    
        printf("Blah blah ...");
    
        getData(&number, string);
        echoPair(number, string);
        return(0);
    }
    

    As an aside, you don't ever want to see unbounded string scans like:

    scanf ("%s", string);
    

    in production-ready code. It's a buffer overflow vulnerability waiting to happen, since you don't control what the user will input. In your particular case, the user entering more than (about) 30 characters may cause all sorts of weird behaviour.

    The scanf function is for scanning formatted text, and there's not many things more unformatted than user input :-)

    If you want a robust user input function, see here.