我的函式試圖做什么的描述
我的函式獲取一個字串,例如 "Ab abc EF aG hi jkL" 并將其轉換為 ["abc", "hi"]
此外,該函式只考慮字母,并且字母都必須是小寫。
問題是
char* str1 = "Ab abc EF aG hi jkL";
char* str2 = "This is a very famous quote";
char** tokens1 = get_tokens(str1);
printf("%s", tokens1[0]); <----- prints out "abc" correct output
char** tokens2 = get_tokens(str2);
printf("%s", tokens1[0]); <----- prints out "s" incorrect output
get_tokens 函式(回傳二維陣列)
char** get_tokens(const char* str) {
// implement me
int num_tokens = count_tokens(str);
char delim[] = " ";
int str_length = strlen(str);
char* new_str = malloc(str_length);
strcpy(new_str, str);
char* ptr = strtok(new_str, delim);
int index = 0;
char** array_2d = malloc(sizeof(char*) *num_tokens);
while (ptr != NULL){
if (check_string(ptr) == 0){
array_2d[index] = ptr;
index ;
}
ptr = strtok(NULL, delim);
}
free(new_str);
new_str = NULL;
free(ptr);
ptr = NULL;
return array_2d;
}
count_tokens 函式(回傳有效字串的數量)
例如 count_tokens("AB abc EF aG hi jkL") 回傳 2 因為只有 "abc" 和 "hi" 有效
int count_tokens(const char* str) {
// implement me
//Seperate string using strtok
char delim[] = " ";
int str_length = strlen(str);
char* new_str = malloc(str_length);
strcpy(new_str, str);
char* ptr = strtok(new_str, delim);
int counter = 0;
while (ptr != NULL){
if (check_string(ptr) == 0){
counter ;
}
ptr = strtok(NULL, delim);
}
free(new_str);
return counter;
}
最后 check_string() 檢查字串是否有效
例如 check_string("Ab") 是無效的,因為里面有一個 A。
使用 strtok 將“Ab abc EF aG hi jkL”拆分為單獨的部分
int check_string(char* str){
// 0 = false
// 1 = true
int invalid_chars = 0;
for (int i = 0; i<strlen(str); i ){
int char_int_val = (int) str[i];
if (!((char_int_val >= 97 && char_int_val <= 122))){
invalid_chars = 1;
}
}
return invalid_chars;
}
任何幫助將非常感激。感謝您的閱讀。
如果您對代碼的作業方式有任何疑問,請詢問我。另外我是stackoverflow的新手,請告訴我是否需要更改某些內容。
uj5u.com熱心網友回復:
您的代碼中有一些問題。首先,我將重復我在評論中所說的話:
- 沒有為字串副本分配足夠的空間。 長度中不
strlen
包含NUL 終止符,因此當您這樣做時
char* new_str = malloc(str_length);
strcpy(new_str, str);
new_str
strcpy
添加時溢位 1 '\0'
,呼叫未定義的行為。您需要額外分配一個:
char* new_str = malloc(str_length 1);
strcpy(new_str, str);
- 您不應該
free
從strtok
. 您只有使用和朋友free
動態分配的記憶體。沒有這樣的事情,所以它回傳的指標是不正確的。這樣做也會呼叫 UB。malloc
strtok
free
你的最后一個問題是因為這個:
// copy str to new_str, that's correct because strtok
// will manipulate the string you pass into it
strcpy(new_str, str);
// get the first token and allocate size for the number of tokens,
// so far so good (but you should check that malloc succeeded)
char* ptr = strtok(new_str, delim);
char** array_2d = malloc(sizeof(char*) *num_tokens);
while (ptr != NULL){
if (check_string(ptr) == 0){
// whoops, this is where the trouble starts ...
array_2d[index] = ptr;
index ;
}
// get the next token, this is correct
ptr = strtok(NULL, delim);
}
// ... because you free new_str
free(new_str);
ptr
是指向new_str
. 只要您free(new_str)
,任何指向該現已釋放記憶體的指標都是無效的。您已經加載了array_2d
指向不再分配的記憶體的指標。嘗試再次訪問這些位置會呼叫未定義的行為。我可以想到兩種方法來解決這個問題:
- 與其保存指向 的偏移量的指標,不如在(來自 的字串)
new_str
中找到相同的標記并指向這些標記。由于這些是在 中定義的,因此只要程式存在,它們就會存在。str
main
main
- 分配更多記憶體,并將
strcpy
令牌放入array_2d[index]
. 我將在下面演示這一點:
while (ptr != NULL){
if (check_string(ptr) == false)
{
// allocate (enough) memory for the pointer at index
array_2d[index] = malloc(strlen(ptr) 1);
// you should _always_ check that malloc succeeds
if (array_2d[index] != NULL)
{
// _copy_ the string pointed to by ptr into our new space rather
// than simply assigning the pointer
strcpy(array_2d[index], ptr);
}
else { /* handle no mem error how you want */ }
index ;
}
ptr = strtok(NULL, delim);
}
// now we can safely free new_str without invalidating anything in array_2d
free(new_str);
我在這里有一個作業演示。請注意演示中的一些其他更改:
#include <stdbool.h>
并使用它而不是 0 和 1int
s。get_tokens
稍微更改了您的功能以“回傳”令牌的數量。main
這對于將它們列印出來很有用。- 用它們的字符替換了 ASCII 幻數。
- 洗掉了無用的
freedPointer = NULL
行。 int
將您的 s更改size_t
為涉及大小的所有內容的型別。
最后一點,雖然這是一個有效的實作,但它可能做的作業比它需要的要多。與其在第一遍中計算令牌的數量,然后在第二遍中檢索它們,您肯定可以在一次遍中完成您想要的所有事情,但如果您愿意,我會將其作為練習留給您。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/430733.html
上一篇:復制派生類的類的建構式