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:
- i assume sentence have @ 10 words, , every word @ 14 characters long (+1 null-terminator).
- allocate dynamically 2d array, of 10 rows , 15 columns.
- initialize of elements zero. did make sure words null terminated. of course skip step , insert null terminator manually @ exact position in
split()
. - split string in tokens.
- print words.
- free dynamically allocated memory of 2d array.
now, let me explain bit more split()
function:
actually attempt pretty good, know doing:
- i loop on string, until meet null terminator.
- as long don't meet whitespace, insert current character in current word.
word_idx
helps me remember word filling now, , character of wordchar_idx
. - when meet whitespace (the
else
case), have advance next word (no need null-terminate string filled before, since have 0 initialized 2d array), incrementingword_idx
1. setchar_idx
0, can start filling new word position 0.
Comments
Post a Comment