c - String not properly being emptied and assigned when dealing with strcpy(string, "") -
edit: did try change line arr_of_strings[arr_index_count] = first_word;
strcpy(arr_of_strings[arr_index_count], first_word);
gives segmentation fault after printing word is: this
edit 2: trying without strtok
since figured way learn c strings.
trying learn c on own. decided create function takes string, , places each word in string element in array. here code:
assume #define max_length = 80
// char *string_one[unknown_size]; // first_word represent each word in sentence char first_word[max_length + 1] = ""; // array store each word in char *arr_of_strings[max_length]; int index_count = 0; int arr_index_count = 0; char sentence[] = "this sentence."; (int = 0; i<max_length; i++) { printf("dealing char: %c\n", sentence[i]); if (sentence[i] == '\0') { // end of sentence break; } else if (sentence[i] == ' ') { // signifies end of word printf("word is: %s\n", first_word); arr_of_strings[arr_index_count] = first_word; // after putting word in string, make word empty again strcpy(first_word, ""); // verify empty printf("first word now: %s\n", first_word); index_count = 0; arr_index_count++; } else { // not start of new string... keep appending letter first_word printf("letter put in first_word is: %c\n", sentence[i]); first_word[index_count] = sentence[i]; index_count++; } } printf("-----------------\n"); (int j = 0; j<=arr_index_count; j++) { printf("%s\n", arr_of_strings[j]); }
what prints is:
dealing char: t letter put in first_word is: t dealing char: h letter put in first_word is: h dealing char: letter put in first_word is: dealing char: s letter put in first_word is: s dealing char: word is: first word now: dealing char: letter put in first_word is: dealing char: s letter put in first_word is: s dealing char: word is: isis first word now: dealing char: letter put in first_word is: dealing char: word is: asis first word now: dealing char: s letter put in first_word is: s dealing char: e letter put in first_word is: e dealing char: n letter put in first_word is: n dealing char: t letter put in first_word is: t dealing char: e letter put in first_word is: e dealing char: n letter put in first_word is: n dealing char: c letter put in first_word is: c dealing char: e letter put in first_word is: e dealing char: . letter put in first_word is: . dealing char: ----------------- sentence. sentence. sentence.
if here:
first word now: dealing char: letter put in first_word is: dealing char: s letter put in first_word is: s dealing char: word is: isis
how come, when word empty, , put
i
,s
it, wordisis
? (sameasis
).how come word
sentence
printed 3 times? algorithm flawed, if anything, shouldn't wordsentence
printed 4 times (once each word in sentence: sentence)?
additionally, i'm learning c if there other ways improve algorithm, please let me know.
based on strtok-free answer, wrote code uses array of n
char pointers, instead of hardcoded 2d matrix.
char matrix[n][len]
2d array, capable of storing n
strings, every string can have len
max length. char *ptr_arr[n]
array of n
char pointers. can store n
strings, length of every string not defined.
current approach allows save space, allocating memory needed every string. hardcoded 2d array, use same memory string; if assumed length of string can 20, allocate memory block of size 20, regardless of string storing, smaller in size 20, or - worse - bigger. in later case, need either cutoff string, or if code not written carefully, invoke undefined behavior, going out of bounds of array storing string.
with pointers' approach not need worry that, , can allocate space need every string, always, trade-off exists. able , save space, need dynamically allocate memory (and when done it, de-allocate it; there no garbage collector in c, in java example). dynamically allocation powerful tool, requires spend more development time.
so, in example, follow same logic before (regarding how find word string, etc.), careful storing words in matrix.
once word found , stored in temporary array word
, able find out exact length of word, using strlen()
. dynamically allocate space length of word suggests, plus 1 null-terminator, c strings should have (since <string.h>
depends on find end of string).
as result, storing first word, "alexander", need do:
ptr_arr[0] = malloc(sizeof(char) * (9 + 1));
where 9 result of strlen("alexander")
. notice ask memory block of size equal size of char
, times 10. size of char
1, in case doesn't make change, in general should use (since yo might want have other data types or structs, etc.).
we make first pointer of array point memory block dynamically allocated. memory block belongs us, , allows store data inside (in our case word). strcpy()
.
afterwards go on , print words.
now done , in python example, finish writing code program. now, since dynamically allocated memory, need free()
it! that's common mistake people do; forget freeing memory asked for!
we freeing every pointer points memory returned malloc()
. if called malloc()
10 times, free()
should called 10 times - otherwise memory leak should occur!
enough talking, here code:
#include <string.h> #include <stdio.h> #include <stdlib.h> #define n 100 int fill(char* ptr_arr[n], char* data) { // how many words in 'data'? int counter = 0; // array store current word, assuming max length 50 char word[50]; // counter 'i' 'word' int i; // wihle there still read 'data' while(*data != '\0') { // seek new word = 0; // while current character of 'data' not whitespace or null-terminator while(*data != ' ' && *data != '\0') // copy character word, , increment 'i'. move next character of 'data'. word[i++] = *data++; // null-terminate 'word'. 'i' @ value desire, line above. word[i] = '\0'; // if current of 'data' not null-terminator (thus it's whitespace) if(*data != '\0') // increment pointer, skip whitespace (and ready read next word) data++; // dynamically allocate space word of length `strlen(word)` // plus 1 null terminator. assign memory chunk // pointer positioned @ `ptr_arr[counter]`. ptr_arr[counter] = malloc(sizeof(char) * (strlen(word) + 1)); // now, `ptr_arr[counter]` points memory block, // store current word. // copy word counter-th row of ptr_arr, , increment counter strcpy(ptr_arr[counter++], word); } return counter; } void print(char* matrix[n], int words_no) { for(int = 0; < words_no; ++i) printf("%s\n", matrix[i]); } void free_matrix(char* matrix[n], int words_no) { for(int = 0; < words_no; ++i) free(matrix[i]); } int main(void) { char data[] = "alexander great"; // store each word of 'data' matrix, of 'n' rows , 'len' columns char *matrix[n]; int words_no; // 'fill()' populates 'matrix' 'data' , returns number of words contained in 'data'. words_no = fill(matrix, data); print(matrix, words_no); free_matrix(matrix, words_no); return 0; }
output:
alexander great
Comments
Post a Comment