为什么我在 C 中遇到 strcat 的问题?

Why am I having this issue with strcat in C?

我是 C 的新手,我的代码如下所示:

//Initialize Global array variable title_char_cnt_array to char[26]
char title_char_cnt_array[26];
//Initialize SearchTitle array
char *SearchTitle[6] = { "uuul", "dule", "speed", "spede", "deul", "cars" };

char *Compute_HashMapKey_for_each_title(char title[]) {
    //char *T;
    //T = title;
    Get_Individual_Character_Frequency_For_Each_Title(title);
    //Initialize alphabets array to char and assign a to z
    //Initialize HashMapKey to char
    char *HashMapKy;
    HashMapKy = malloc(sizeof(char));
    char default_str[] = { "0#" };
    char str[50];
    char ash[] = { "#" };
    int i;
    //Create HashMapKey by appending 0# to HashMapKey if a particular alphabet isn't in title or   count_of_alphabet plus # if the alphabet is in title (the format is   1#0#1#0#1#0#0#0#0#0#0#0#0#0#1#0#0#2#0#2 ... #1#0#0# for this title: Extractor for e.g)
    for (i = 0; i < 26; i++) {
        if (title_char_cnt_array[i] == 0) {
            //HashMapKey = HashMapKey . '0#';
            strcat(HashMapKy, default_str);
        } else {
            //First convert character frequency count to string
            sprintf(str, "%d", title_char_cnt_array[i]);
            //concat # to str
            strcat(str, ash);
            //HashMapKey =. title_char_cnt_array[i].'#';
            strcat(HashMapKy, str);
        }//end if
    }//End For
    return HashMapKy;
}

void Get_Individual_Character_Frequency_For_Each_Title(char Title[]) {
    int Title_Size;
    //get size of Title
    Title_Size = strlen(Title);
    int x, j;
    //Initialize current_char to char for character comparison in title_array
    char current_char;
    char Alphabets[][1] =  { "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z" };
    //Foreach character in title array, calculate individual character frequency here
    for (x = 0; x < Title_Size; x++) {
        //Initialize current_char_cnt to 0
        int current_char_cnt = 1;
        current_char = *(Title + x);//retrieve each character of Title array
        for (j = x; j < Title_Size; j++) {
            if (current_char == *(Title + j + 1)) {
                //increment current_char_cnt
                current_char_cnt++;
            }//End If
        }
        /*Insert current_char_cnt in title_char_cnt_array against index - index no. represents position of char in alphabetical order*/
        if (current_char == Alphabets[0][0])
            if (title_char_cnt_array[0] == 0)//if no previous value inserted, then insert
                title_char_cnt_array[0] = current_char_cnt;
        if (current_char == Alphabets[1][0])
            if (title_char_cnt_array[1] == 0)
                title_char_cnt_array[1] = current_char_cnt;
        if (current_char == Alphabets[2][0])
            if (title_char_cnt_array[2] == 0)
                title_char_cnt_array[2] = current_char_cnt;
        if (current_char == Alphabets[3][0])
            if (title_char_cnt_array[3] == 0)
                title_char_cnt_array[3] = current_char_cnt;
        if (current_char == Alphabets[4][0])
            if (title_char_cnt_array[4] == 0)
                title_char_cnt_array[4] = current_char_cnt;
        if (current_char == Alphabets[5][0])
            if (title_char_cnt_array[5] == 0)
                title_char_cnt_array[5] = current_char_cnt;
        if (current_char == Alphabets[6][0])
            if (title_char_cnt_array[6] == 0)
                title_char_cnt_array[6] = current_char_cnt;
        if (current_char == Alphabets[7][0])
            if (title_char_cnt_array[7] == 0)
                title_char_cnt_array[7] = current_char_cnt;
        if (current_char == Alphabets[8][0])
            if (title_char_cnt_array[8] == 0)
                title_char_cnt_array[8] = current_char_cnt;
        if (current_char == Alphabets[9][0])
            if (title_char_cnt_array[9] == 0)
                title_char_cnt_array[9] = current_char_cnt;
        if (current_char == Alphabets[10][0])
            if (title_char_cnt_array[10] == 0)
                title_char_cnt_array[10] = current_char_cnt;
        if (current_char == Alphabets[11][0])
            if (title_char_cnt_array[11] == 0)
                title_char_cnt_array[11] = current_char_cnt;
        if (current_char == Alphabets[12][0])
            if (title_char_cnt_array[12] == 0)
                title_char_cnt_array[12] = current_char_cnt;
        if (current_char == Alphabets[13][0])
            if (title_char_cnt_array[13] == 0)
                title_char_cnt_array[13] = current_char_cnt;
        if (current_char == Alphabets[14][0])
            if (title_char_cnt_array[14] == 0)
                title_char_cnt_array[14] = current_char_cnt;
        if (current_char == Alphabets[15][0])
            if (title_char_cnt_array[15] == 0)
                title_char_cnt_array[15] = current_char_cnt;
        if (current_char == Alphabets[16][0])
            if (title_char_cnt_array[16] == 0)
                title_char_cnt_array[16] = current_char_cnt;
        if (current_char == Alphabets[17][0])
            if (title_char_cnt_array[17] == 0)
                title_char_cnt_array[17] = current_char_cnt;
        if (current_char == Alphabets[18][0])
            if (title_char_cnt_array[18] == 0)
                title_char_cnt_array[18] = current_char_cnt;
        if (current_char == Alphabets[19][0])
            if (title_char_cnt_array[19] == 0)
                title_char_cnt_array[19] = current_char_cnt;
        if (current_char == Alphabets[20][0])
            if (title_char_cnt_array[20] == 0)
                title_char_cnt_array[20] = current_char_cnt;
        if (current_char == Alphabets[21][0])
            if (title_char_cnt_array[21] == 0)
                title_char_cnt_array[21] = current_char_cnt;
        if (current_char == Alphabets[22][0])
            if (title_char_cnt_array[22] == 0)
                title_char_cnt_array[22] = current_char_cnt;
        if (current_char == Alphabets[23][0])
            if (title_char_cnt_array[23] == 0)
                title_char_cnt_array[23] = current_char_cnt;
        if (current_char == Alphabets[24][0])
            if (title_char_cnt_array[24] == 0)
                title_char_cnt_array[24] = current_char_cnt;
        if (current_char == Alphabets[25][0])
            if (title_char_cnt_array[25] == 0)
                title_char_cnt_array[25] = current_char_cnt;
    }//End For
}

int main() {
    int i;
    //Foreach element in title_char_cnt_array, assign an in value of -1
    for (i = 0; i < 26; i++)
        title_char_cnt_array[i] = 0;

    //Initialize HashMap array
    struct node *HashMap[9];
    int HM_indx = 0;
    for (HM_indx = 0; HM_indx < 9; HM_indx++)
        HashMap[HM_indx] = NULL;
    int sz = 6; //6 titles to insert in hashmap
    //Initialize SearchTitle array
    //char *SearchTitle[6] = { "uuul", "dule", "speed", "spede", "deul", "cars" };

    char *HMKey;
    int x;
    for (x = 0; x < sz; x++) {
        HMKey = Compute_HashMapKey_for_each_title(SearchTitle[x]);
        //printf("%s\n", HMKey);
        Insert_Title_To_HashMap_Using_HashMapKey(x, HMKey, HashMap);
    }

    free(HMKey);
    return 0;
}

我期望 Compute_HashMapKey_for_each_title(SearchTitle[x]) 到 return 到 HMKeymain 函数中是:

HashMapKey="0#0#0#0#0#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#3#0#0#0#0#0#"

但我使用调试器看到的是:

HashMapKey=0xb41700 "À", '«' <repeats 16 times>, "þîþîþîþîþîþîþîþ0#0#0#0#0#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#3#0#0#0#0#0#"

main函数可以看出,一旦我得到HMKey;我将它传递给函数 Insert_Title_To_HashMap_Using_HashMapKey(x, HMKey, HashMap),然后将我期望的字符串:"0#0#0#0#0#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#3#0#0#0#0#0#" 分解为单个字符,将每个字符转换为其 ASCII 码,然后求和。所以我希望看到 0 作为第一个字符,# 作为第二个字符,0 作为第三个字符等等,但是我看到的第一个字符使用调试器是ÀCompute_HashMapKey_for_each_title(SearchTitle[x]) 到 return 到 HMKey.

的 return 值中地址后的第一个字符

在这种情况下,即使是我预期的 strlen 也应该是 52,但我看到的是:84.

我不知道发生了什么,非常感谢您的帮助。

HashMapKy = malloc(sizeof(char));

您只为单个字符分配了space。 C 中的数组或内存不是动态的,您不能仅通过附加到它们来“扩展”内存或数组。

此外,strcat 函数要求两个字符串都是以 null 结尾的字符串。由于 malloc 函数不会初始化它分配的内存,因此它的内容将是 indeterminate (最好将其视为垃圾或随机)。它不太可能在第一个位置包含零(空终止符)。

你应该 malloc 大小 HashMapKy = (char*) malloc (sizeof(char) * 25);

Compute_HashMapKey_for_each_title中存在一个主要问题:您没有为散列字符串分配足够的 space,malloc(sizeof(char)) 分配了一个字节。

字符串可以大到 26 乘以 5 加上空终止符(如果 title_char_cnt_arraychar 的数组则为 5 字节,但如果将其更改为 int 则为 12 ).我建议使用本地数组并使用 strdup():

返回分配的副本
char *Compute_HashMapKey_for_each_title(char title[]) {
    char buf[26 * 12 + 1];
    int pos = 0;
    Get_Individual_Character_Frequency_For_Each_Title(title);
    // Create HashMapKey by appending the number of occurrences for each character
    //  followed by a `#` char.
    for (int i = 0; i < 26; i++) {
        pos += sprintf(buf + pos, "%d#", title_char_cnt_array[i]);
    }
    return strdup(buf);
}

函数Get_Individual_Character_Frequency_For_Each_Title可以大大简化:

void Get_Individual_Character_Frequency_For_Each_Title(char Title[]) {
    const char *alphabet = "abcdefghijklmnopqrstuvwyxz";
    for (int i = 0; i < 26; i++) {
        title_char_cnt_array[i] = 0;
    }
    for (int i = 0; Title[i] != '[=11=]'; i++) {
        char *p = strchr(alphabet, Title[i]);
        if (p != NULL) {
            title_char_cnt_array[p - alphabet] += 1;
        }
    }
}

如果能假设系统使用ASCII字符集,函数就更简单了:

void Get_Individual_Character_Frequency_For_Each_Title(char Title[]) {
    for (int i = 0; i < 26; i++) {
        title_char_cnt_array[i] = 0;
    }
    for (int i = 0; Title[i] != '[=12=]'; i++) {
        char c = Title[i];
        if (c >= 'a' && c <= 'z') {
            title_char_cnt_array[c - 'a'] += 1;
        }
    }
}

请注意,title_char_cnt_array 应作为参数传递,并且应具有大于 char 的整数类型。