c - how to use pointer to pointer to slice string -


i read pointer pointers on tutorialspoint.

i had little test myself. want slice string space every words (include punctuation) treated token , tokens returned line line.

here code:

#include <stdio.h> #include <string.h> #include <stdlib.h>  char** split(const char* s) {     int = 0, j = 0;     char** word = malloc(strlen(s)+1);     * word = malloc(strlen(s)+1);      while (*s != '\0') {         if (*s == ' ') {             i++;         } else {             word[i][j] = *s;             j++;         }         i++;         s++;     }      return word;     //free(word);  //with or without same outcome. }  int main(void) {     char** words = split("he said 'hello' me!");     int = 0;     while (words[i] != null) {         puts(words[i]);         free(words[i]);         += 1;     }     free(words); } 

it compiles when run on terminal segmentation fault. added printf in if statement, prints every letter.

i used valgrind, cannot understand saying.

expected output:

he said 'hello' me! 

first, comment on attempt:

here:

return word; free(word); 

free won't executed! see lies after return statement, doesn't execute!

moreover, space allocated dynamically malloc() wrong, check how in 2d dynamic array, or/and read example below.

you see, without having allocated sufficient, accessing out of bound memory, cause undefined behavior, lucky segmentation fault, alerted you! :)

i won't debug code, since it's wonderful chance practice, if want ask more.

here how it, it's simpler approach, if that, able work on own attempt! :)

#include <stdio.h> #include <string.h> #include <stdlib.h>  // return pointer char **get(int n, int m) // allocate array */ {     // todo: check if allocation succeeded. (check null pointer)     int i;     char** table;     table = malloc(n*sizeof(char *));     for(i = 0 ; < n ; i++)         table[i] = malloc( m*sizeof(char) );     return table; }  void free2darray(char** p, int n) {     int i;     for(i = 0 ; < n ; i++)         free(p[i]);     free(p); }  void zerofill(char** p, int n, int m) {     int i, j;     for(i = 0 ; < n ; i++)         for(j = 0 ; j < m ; j++)             p[i][j] = 0; }  void print(char** p, int n, int m) {     int i;     for(i = 0 ; < n ; i++)         if(strlen(p[i]) != 0)             printf("array[%d] = %s\n", i, p[i]); }  void split(const char* s, char** words) {     int = 0, word_idx = 0, char_idx = 0;     while(s[i] != '\0') {         if(s[i] != ' ') {             words[word_idx][char_idx++] = s[i];         } else {             word_idx++;             char_idx = 0;         }         ++i;     } }  int main(void) {     char** words = get(10, 15); // 10 words, 14 chars max (+1 n$     zerofill(words, 10, 15);      split("he said 'hello' me!", words);     print(words, 10, 15);      free2darray(words, 10);     return 0;  } 

output:

c02qt2ubfvh6-lm:~ gsamaras$ nano main.c c02qt2ubfvh6-lm:~ gsamaras$ gcc -wall main.c  c02qt2ubfvh6-lm:~ gsamaras$ ./a.out  array[0] = array[1] = said array[2] = 'hello' array[3] = array[4] = me! 

the explanation:

  1. i assume sentence have @ 10 words, , every word @ 14 characters long (+1 null-terminator).
  2. allocate dynamically 2d array, of 10 rows , 15 columns.
  3. initialize of elements zero. did make sure words null terminated. of course skip step , insert null terminator manually @ exact position in split().
  4. split string in tokens.
  5. print words.
  6. free dynamically allocated memory of 2d array.

now, let me explain bit more split() function:

actually attempt pretty good, know doing:

  1. i loop on string, until meet null terminator.
  2. as long don't meet whitespace, insert current character in current word. word_idx helps me remember word filling now, , character of word char_idx.
  3. when meet whitespace (the else case), have advance next word (no need null-terminate string filled before, since have 0 initialized 2d array), incrementing word_idx 1. set char_idx 0, can start filling new word position 0.

Comments