My goal is to read input from the user and store each word given by the user in a dynamically allocated array which I called "str". However, I have two problems. One, in the function leArgs when reading an argument after the first one, if I try to print it using arg[agrs] (args > 0) it gives me SEGFAULT. Second, if I only give 1 word, the leArgs works, but it doesn't store anything in "str", giving me SEGFAULT after I try to print its first argument.
If I was confusing or not clear enough comment and I will rewrite it! My code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define INVERSO "inverso" /* String representativa da chave para impressão
do percurso duma carreira por ordem inversa */
#define LEN_INVERSO 8 /* Comprimento da chave representativa */
#define TRUE 1 /* verdadeiro */
#define FALSE 0 /* falso */
#define FIM_LINHA -1 /* fim de linha */
#define NOTVALID -1 /* não é valido*/
#define BUFFER 65535
enum arg {PRIMEIRO, SEGUNDO, TERCEIRO, QUARTO, QUINTO};
int is_space ( int c ) {
return (c == '\t' || c == ' ' || c == '\n');
}
/* Recebe um char e retorna True se for um fim de linha
e false caso contrario */
int NotEndOfLine ( char character ) {
return character != '\n';
}
int leNome ( char *buff ) {
int character, aspas = FALSE, i = 0;
while ( is_space (character = getchar()) ) {
if ( !NotEndOfLine(character) )
return FIM_LINHA;
}
do {
if (character == '"')
aspas = (aspas == FALSE) ? TRUE : FALSE;
else
buff[i++] = character;
} while ( !is_space(character = getchar() ) || aspas == TRUE );
buff[i++] = '\0';
return !NotEndOfLine ( character );
}
int leArgs ( char **arg ) {
int num_args = 0, args = PRIMEIRO, lenght, endline;
char buff[BUFFER];
do {
endline = leNome( buff );
printf("Run: %d\n" , args);
if ( endline == FIM_LINHA )
return num_args;
arg = (char**) realloc ( arg, sizeof (char*) * (++num_args)) ;
lenght = strlen(buff);
arg[args] = (char *) malloc (sizeof (char) * (lenght + 1) );
strcpy( arg[args] , buff );
printf("buff:%s arg:%d num_args:%d\n", buff, args, num_args);
printf( "Argumento: %s\n", arg[args] );
putchar('\n');
args++;
} while ( endline == FALSE ) ;
return num_args;
}
int main(){
int i, num_args;
char **str = NULL;
num_args = leArgs( str );
printf( "%s ", str[0]);
puts( "sucesso ");
for(i = 0; i < num_args; i++){
printf("i:%d",i);
printf("%d:%s\n",i,str[i]);
}
return 0;
}
You are passing the pointer str
to the function leArgs
by value
char **str = NULL;
num_args = leArgs( str );
It means that the function deals with a copy of the original pointer. Changing the copy within the function does not change the original pointer.
You need to pass it by reference through a pointer to it.
That is the function should be declared like
int leArgs ( char ***arg );
and called like
num_args = leArgs( &str );
Within the function you need to write at least like for example
*arg = (char**) realloc ( *arg, sizeof (char*) * (++num_args));
though it will be safer to use an intermediate pointer like for example
char **tmp = realloc ( *arg, sizeof (char*) * (++num_args));
if ( tmp != NULL ) *arg = tmp;