int string_split(char* string,char ** array_results){ static int word_count; if( string == 0){ return word_count; }//конец строки if( string-1 == 0){ //если предыдущий символ 0, то это слово *array_results = &string; array_results++; word_count++; } if(*string == ' '){ string = 0; } return string_split(++string,array_results); } 

It is necessary to divide the line into words and as a result get an array of pointers to words. For some reason gives an error

 warning: assignment from incompatible pointer type *array_results = &string 
  • That's right, why look for easy ways in the form of strtok() :-) - PinkTux

3 answers 3

To begin with, the function does not make sense and, moreover, has an undefined behavior, even if the code were compiled.

So, in this code snippet

  if(*string == ' '){ string = 0; } return string_split(++string,array_results); 

the value of the string pointer is set to 0. And then in a recursive function call, this pointer value is incremented by 1. As a result, the next time the function is called, the string pointer is 1, and memory is accessed at this invalid address.

Further in this sentence

 if( string-1 == 0){ ^^^^^^^^ 

not the string character is compared with 0, but the value of the string - 1 pointer string - 1 with zero.

As for the compiler error, it does not matter much in the context of what has been said, since in any case this function is not correct. However, the error is related to the proposal.

 *array_results = &string; 

since the left operand is of the char * type, as a consequence of dereferencing a pointer of the char ** type, and the right operand is of the char ** type due to the use of the address operator to an object of the char * type

But, as I already wrote, it does not matter much, since you need to completely rewrite the function again.

The function may look like this, as shown in the demo below.

 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> size_t string_split( const char *s, char ***a ) { static int count = 0; size_t n = 0; if ( s ) { if ( *s == '\0' ) { count = 0; } else { if ( !isblank( ( unsigned char )*s ) && ( count == 0 || isblank( ( unsigned char )s[-1] ) ) ) { ++count; n = 1; char **tmp = realloc( *a, count * sizeof( char * ) ); if ( tmp ) { *a = tmp; ( * a )[count -1] = ( char * )s; } else { free( *a ); *a = NULL; count = 0; n = -1; } } if ( n != -1 ) { size_t i = string_split( s + 1, a ); n = i == -1 ? i : n + i; } } } return n; } int main( void ) { char *s1 = "Hello function string_split"; char **a = NULL; size_t n = string_split( s1, &a ); if ( n != -1 ) { for ( size_t i = 0; i < n; i++ ) puts( a[i] ); free( a ); a = NULL; } char *s2 = "ABCDEFG"; n = string_split( s2, &a ); if ( n != -1 ) { for ( size_t i = 0; i < n; i++ ) puts( a[i] ); free( a ); a = NULL; } return 0; } 

The output of the program to the console:

 Hello function string_split function string_split string_split ABCDEFG BCDEFG CDEFG DEFG EFG FG G 

    Judge for yourself:

     *array_results = &string 

    array_results has type char** , i.e. *array_results is of type char* .

    string has type char* , so &string has type char** .

    so these types are really completely different ...

    In general, I would do this (if, of course, recursion is needed, words are separated by spaces, etc etc ...):

     int string_split(char* str, char ** array_results) { if(str == 0) { return 0; } while(*str == ' ') ++str; if (*str == 0) { return 0; } *array_results++ = str; while(*str && *str != ' ') ++str; if (*str == 0) { return 1; } else { *str = 0; } return 1 + string_split(str+1,array_results); } 

      And to heap:

       static int word_count; if( string == 0){ return word_count; }//конец строки /* ... */ 

      When first accessed, the word_count value will indeed be 0 . And the next? It will start with the value calculated on the previous function call. And the fact that it is used in recursion, does not save from this.

      But there is more to this with this fragment :)

       return string_split(++string,array_results); 

      What do you think, at which point the value of the string pointer will become zero?

      Right, this one!

       if(*string == ' '){ string = 0; }