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 anint, the value of which the application shall ensure is a character representable as anunsigned charof equal value that terminates the read process. If the delimiter argument has any other value, the behavior is undefined.The application shall ensure that
*lineptris a valid argument that could be passed to thefree()function. If*nis non-zero, the application shall ensure that*lineptreither points to an object of size at least*nbytes, or is anullpointer.If
*lineptris anullpointer or if the object pointed to by*lineptris of insufficient size, an object shall be allocated as if bymalloc()or the object shall be reallocated as if byrealloc(), respectively, such that the object is large enough to hold the characters to be written to it, including the terminatingNUL, and*nshall be set to the new size. If the object was allocated, or if the reallocation operation moved the object,*lineptrshall 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 terminatingNULadded when the delimiter or end-of-file is encountered.The
getline()function shall be equivalent to thegetdelim()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.
