Home > Net >  C struggling with getline() - incompatible integer to pointer conversion
C struggling with getline() - incompatible integer to pointer conversion

Time:08-07

I need my program to gather random user input in order to return the number of character as odd or even (return ( strlen ( &raw_scrap ) % 2 ) ;)

I can't get the getline() function to work properly from char raw_scrap global declaration.

Here are the warnings I get:

$clang geomant.c -o geomant.bin
geomant.c:61:12: warning: incompatible integer to pointer conversion passing 'char' to parameter of type 'char **' [-Wint-conversion]
        getline ( raw_scrap, sizeof(&raw_scrap), stdin ) ;
                  ^~~~~~~~~
/usr/include/stdio.h:239:36: note: passing argument to parameter here
ssize_t  getline(char ** __restrict, size_t * __restrict,
                                   ^
geomant.c:61:23: warning: incompatible integer to pointer conversion passing 'unsigned long' to parameter of type 'size_t *' (aka 'unsigned long *') [-Wint-conversion]
        getline ( raw_scrap, sizeof(&raw_scrap), stdin ) ;
                             ^~~~~~~~~~~~~~~~~~
/usr/include/stdio.h:239:57: note: passing argument to parameter here
ssize_t  getline(char ** __restrict, size_t * __restrict,
                                                        ^
2 warnings generated.

Here's my full code (omit repetitive arrays for compactness/readability):

/*****************************************/
/*     Geomant : a basic implementation  */
/*  of the geomanteia intended as a first*/
/*  C training project                   */
/*  copyright \xc2\xa9 Sylvain Saboua    */
/*  <sylvain ! saboua (|) free ! fr>     */
/*****************************************/

# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <unistd.h>

char *body_parts[] = { "head", "neck", "body", "legs" } ;
char *mother_figures[] = { "1st", "2nd", "3rd", "4th" } ;

int n_figure ;
int n_bodypart ;

char raw_scrap ;
char *figures[15][4] = {
        // mothers
        {"* *", "* *", "* *", "* *"},
        {"* *", "* *", "* *", "* *"},
        {"* *", "* *", "* *", "* *"},
        {"* *", "* *", "* *", "* *"},

        // daughters
        {"* *", "* *", "* *", "* *"},
        {"* *", "* *", "* *", "* *"},
        {"* *", "* *", "* *", "* *"},
        {"* *", "* *", "* *", "* *"},

        // nieces
        {"* *", "* *", "* *", "* *"},
        {"* *", "* *", "* *", "* *"},
        {"* *", "* *", "* *", "* *"},
        {"* *", "* *", "* *", "* *"},

        // witnesses & judge
        {"* *", "* *", "* *", "* *"},
        {"* *", "* *", "* *", "* *"},
        {"* *", "* *", "* *", "* *"}
} ;

/*

        "mantize" : input fuction

 This function gathers a string of user input
 and returns a 0 or 1 for the evenness or
 oddity of the number of characters. It is called
 in a sequence by the next function to generate
 the figures one by one.

*/

int mantize ( int n_bodypart, int n_figure ) {
        printf ( "Hold or repeatedly press a key or keys to generate the %s of the %s mother
, then press Enter:\n",
                body_parts[n_bodypart], mother_figures[n_figure] ) ;
        getline ( raw_scrap, sizeof(&raw_scrap), stdin ) ;
        return ( strlen ( &raw_scrap ) % 2 ) ;
}

/*

        "generate" fuction:

 This function takes the cast result (being 0 or 1,
 odd or even) and use it to generate
 all 15 figures, from the mothers down to the
 daughters, nieces, witnesses and judge.

*/

int generate(){

        // generating the mothers

        for ( n_figure = 0 ; n_figure < 4 ; n_figure   ) {
                for ( n_bodypart = 0 ; n_bodypart < 4 ; n_bodypart   ) {
                        figures[n_figure][n_bodypart] =
                        (0 == mantize(n_bodypart, n_figure)) ? "* *" : "*" ;
                }
        }

        //generating the four daughters from the four mothers

        figures[4][0] = figures[0][0] ;
        figures[4][1] = figures[1][0] ;
        figures[4][2] = figures[2][0] ;
        figures[4][3] = figures[3][0] ;

        figures[5][0] = figures[0][1] ;
        figures[5][1] = figures[1][1] ;
        figures[5][2] = figures[2][1] ;
        figures[5][3] = figures[3][1] ;

        figures[6][0] = figures[0][2] ;
        figures[6][1] = figures[1][2] ;
        figures[6][2] = figures[2][2] ;
        figures[6][3] = figures[3][2] ;

        figures[7][0] = figures[0][3] ;
        figures[7][1] = figures[1][3] ;
        figures[7][2] = figures[2][3] ;
        figures[7][3] = figures[3][3] ;

        // generating the nieces

        figures[8][0] = ( figures[0][0] == figures[1][0] ) ? "* *" : " * " ;
        figures[8][1] = ( figures[0][1] == figures[1][1] ) ? "* *" : " * " ;
        figures[8][2] = ( figures[0][2] == figures[1][2] ) ? "* *" : " * " ;
        figures[8][3] = ( figures[0][3] == figures[1][3] ) ? "* *" : " * " ;

        figures[9][0] = ( figures[2][0] == figures[3][0] ) ? "* *" : " * " ;
        figures[9][1] = ( figures[2][1] == figures[3][1] ) ? "* *" : " * " ;
        figures[9][2] = ( figures[2][2] == figures[3][2] ) ? "* *" : " * " ;
        figures[9][3] = ( figures[2][3] == figures[3][3] ) ? "* *" : " * " ;

        figures[10][0] = ( figures[4][0] == figures[5][0] ) ? "* *" : " * " ;
        figures[10][1] = ( figures[4][1] == figures[5][1] ) ? "* *" : " * " ;
        figures[10][2] = ( figures[4][2] == figures[5][2] ) ? "* *" : " * " ;
        figures[10][3] = ( figures[4][3] == figures[5][3] ) ? "* *" : " * " ;

        figures[11][0] = ( figures[6][0] == figures[7][0] ) ? "* *" : " * " ;
        figures[11][1] = ( figures[6][1] == figures[7][1] ) ? "* *" : " * " ;
        figures[11][2] = ( figures[6][2] == figures[7][2] ) ? "* *" : " * " ;
        figures[11][3] = ( figures[6][3] == figures[7][3] ) ? "* *" : " * " ;

        // generating the witnesses

        figures[12][0] = ( figures[8][0] == figures[9][0] ) ? "* *" : " * " ;
        figures[12][1] = ( figures[8][1] == figures[9][1] ) ? "* *" : " * " ;
        figures[12][2] = ( figures[8][2] == figures[9][2] ) ? "* *" : " * " ;
        figures[12][3] = ( figures[8][3] == figures[9][3] ) ? "* *" : " * " ;

        figures[13][0] = ( figures[10][0] == figures[11][0] ) ? "* *" : " * " ;
        figures[13][1] = ( figures[10][1] == figures[11][1] ) ? "* *" : " * " ;
        figures[13][2] = ( figures[10][2] == figures[11][2] ) ? "* *" : " * " ;
        figures[13][3] = ( figures[10][3] == figures[11][3] ) ? "* *" : " * " ;

        //generating the judge

        figures[14][0] = ( figures[12][0] == figures[13][0] ) ? "* *" : " * " ;
        figures[14][1] = ( figures[12][1] == figures[13][1] ) ? "* *" : " * " ;
        figures[14][2] = ( figures[12][2] == figures[13][2] ) ? "* *" : " * " ;
        figures[14][3] = ( figures[12][3] == figures[13][3] ) ? "* *" : " * " ;

        return *figures[14][3] ;

}


/*

        "display" function:

 This function will display onscreen the final
 geomantic Shield for the given divination.
 The "-" & "|" characters are used for separation
 while the dots are displayed using "*"

*/
int main(){

        generate();

        //printf(*figures);

        /*
        printf(" --- ")
        for i in .*
        return(*raw_scrap[3][3]);
        */

}

CodePudding user response:

You are misusing getline(). You're passing a char value as getline()'s first argument, instead of the required char ** pointer-to-pointer-to-char.

Per the POSIX getline() documentation (Pay particular attention to the bolded second paragraph of the description section):

SYNOPSIS

#include <stdio.h>

ssize_t getdelim(char **restrict lineptr, size_t *restrict n,
       int delimiter, FILE *restrict stream);
ssize_t getline(char **restrict lineptr, size_t *restrict n,
       FILE *restrict stream);

DESCRIPTION

The getdelim() function shall read from stream until it encounters a character matching the delimiter character. The delimiter argument is an int, the value of which the application shall ensure is a character representable as an unsigned char of equal value that terminates the read process. If the delimiter argument has any other value, the behavior is undefined.

The application shall ensure that *lineptr is a valid argument that could be passed to the free() function. If *n is non-zero, the application shall ensure that *lineptr either points to an object of size at least *n bytes, or is a null pointer.

If *lineptr is a null pointer or if the object pointed to by *lineptr is of insufficient size, an object shall be allocated as if by malloc() or the object shall be reallocated as if by realloc(), respectively, such that the object is large enough to hold the characters to be written to it, including the terminating NUL, and *n shall be set to the new size. If the object was allocated, or if the reallocation operation moved the object, *lineptr shall be updated to point to the new object or new location. The characters read, including any delimiter, shall be stored in the object, and a terminating NUL added when the delimiter or end-of-file is encountered.

The getline() function shall be equivalent to the getdelim() function with the delimiter character equal to the <newline> character.

A correct use of getline() would look more like this:

char *raw_scrap = NULL;
size_t raw_scrap_size = 0UL;
   .
   .
   .
        getline ( &raw_scrap, &raw_scrap_size, stdin ) ;

getline() reads an entire line of input - you'll have to change your program to work with lines, not individual char inputs.

Note that raw_scrap must be a pointer to char and the address of that pointer must be passed to getline(), and the second argument is the address of an actual size_t variable, not a constant result from calling sizeof(), which isn't an address.

Note also the values contained in those arguments must comply with the restrictions noted in the POSIX standard.

  • Related