簡體   English   中英

C比較2個字符串變成內存分配問題

[英]C Comparing 2 strings turned into memory allocation issue

首先,我要說的是,我的確知道有很多題目完全相同的問題,但是我沒有找到我所要查找的內容。 我試圖編寫以下代碼,以便對用戶的輸入進行錯誤檢查,因此他不會給2個變量使用相同的名稱。 不用說,它失敗了,這就是為什么我在這里。 在打印字符串時,我使用printf("%s", temp[j].name);作為字符串進行比較printf("%s", temp[j].name); 工作正常,逐個字符打印輸出了一系列字符,據我所知,這些字符不應該在那里。 我想知道這可能是怎么回事,以及是否有解決的辦法,因此我實際上可以比較2,而無需使用string.h

這是代碼:

#include <stdio.h>
#include <stdlib.h>

#define ARRAYLENGTH 20

typedef struct{
    char name[ARRAYLENGTH];
    char type[ARRAYLENGTH];
    char value[ARRAYLENGTH];
}variable;


int main(){
    int amount = 3;
    int i, j, k;
    variable * varray;
    variable * temp;
    int flag;
    int added = 1;

    varray = malloc(amount*sizeof(variable));
    if (varray == NULL){
        printf("error");
        return 1;
    }
        temp = malloc(amount*sizeof(variable));
    if (temp == NULL){
        printf("error");
        return 1;
    }
    printf("Give the name of variable # 1 \n");
    scanf("%s", varray[0].name);

    for (i = 1; i < amount; i++){
        flag = 0;
        while (flag == 0){
            printf("Give the name of variable # %d \n", i + 1);
            scanf("%s", temp[i].name);

            for (j = 0; j < added; j++){
                for (k = 0; temp[i].name[k] != '\0'; k++){
                    printf("%c,", temp[i].name[k]);
                }
                printf("\n");
                for (k = 0; temp[i].name[k] != '\0'; k++){
                    if (varray[j].name[k] != temp[i].name[k]){
                        flag = 1;
                        break;
                    }
                    if (varray[j].name[k] == temp[i].name[k]){
                        flag = 0;
                    }
                }
            }
            if (flag == 0){
                printf("The variable name you gave already exists, please choose another one. \n");
            }
            if (flag == 1){
                for (j = 0; j < ARRAYLENGTH; j++){
                    varray[i].name[j] = temp[i].name[j];
                }
            }
            if(flag == 1){
                added +=1;
            }
        }
    }
    for (i = 0; i < amount; i++){
        printf("%s \n", varray[i].name);
    }
    free(varray);
    free(temp);
}

代碼可以毫無問題地編譯,但是當我嘗試運行它時,我發現,無論我作為用戶輸入什么內容,該標志的末尾始終為1。 代碼塊

printf("\n");
for (k = 0; k < ARRAYLENGTH; k++){
    printf("%c,", temp[i].name[k]);
}
printf("\n");

當用戶輸入的名稱為John時,在Visual Studio 2013的Developer命令提示符下輸出以下內容:

Give the name of variable # 1                                                                                                                         
John                                                                                                                                                  
Give the name of variable # 2                                                                                                                         
John                                                                                                                                                  
J,o,h,n,                                                                                                                                              
The variable name you gave already exists, please choose another one.                                                                                 
Give the name of variable # 2                                                                                                                         
George                                                                                                                                                
G,e,o,r,g,e,                                                                                                                                          
Give the name of variable # 3 
George                                                                                                                                                
G,e,o,r,g,e,                                                                                                                                          
G,e,o,r,g,e,                                                                                                                                          
The variable name you gave already exists, please choose another one.                                                                                 
Give the name of variable # 3                                                                                                                         
John                                                                                                                                                  
J,o,h,n,                                                                                                                                              
J,o,h,n,                                                                                                                                              
John                                                                                                                                                  
George                                                                                                                                                
John                 

我猜這個問題是關於系統分配給temp的內存,而varray已在其他地方使用。 此錯誤檢查對於我必須執行的項目至關重要,因此,我將在解決此問題方面大有幫助。 提前致謝,

LukeSykpe

問題出在您的打印邏輯上。

scanf函數將用戶輸入寫入數組,后跟一個終止的\\ 0字符。 它不知道數組的大小(20),因此它不會觸及實際上未寫入的數組部分。

代替這個:

for (k = 0; k < ARRAYLENGTH; k++){

寫:

for (k = 0; temp[i].name[k] != '\0'; k++) {

請注意,您無需在此處檢查是否耗盡了數組的末尾。 相反,請確保用戶字符串對於您的陣列而言不要太大。 看到這個如何做。

編輯:這篇文章不是回答原始問題,而是回答評論中張貼的后續問題。 我試圖將其合並到先前的答案中,但所有者拒絕了。 就是這樣

varray比較的問題在於,至少在您顯示的代碼中,varray從未初始化。 所以

if (varray[j].name[k] != temp[i].name[k])

有點像在內存中獲取隨機字節,將其分配給變量,然后執行以下操作:

if (RandomByteValue != temp[i].name[k])

哪90%的時間是正確的,因此將標志設置為1。本質上,您缺少

varray[i] = lastVariableGotFromUser

在每個主循環的末尾。

---編輯:對一般功能進行了較小的更正---

嘗試添加:

int added = 1;

然后更改:

for (j = 0; j < amount; j++){

與:

for (j = 0; j < added; j++){

並添加:

        if (flag == 1){
            // Your for loop
            added += 1;
        }

發生的事情是,您遍歷未初始化且包含隨機內存的varray字段。 進行了這些修改(如果我沒有忘記一個修改,它應該可以工作。請嘗試始終將循環限制為僅有用的迭代。如果您知道僅添加了一個變量,請不要遍歷3個字段。

-------最后編輯以更正其代碼中的細節-------

所以,你整個:

for (k = 0; temp[i].name[k] != '\0'; k++){

可以刪除。 現在我也知道您不想使用string.h,但是,重新編碼strcmp並不是那么復雜。 叫它吧

int comp_str(str, str2) // Returns 1 if they don't match, zero if they do.

然后只需將整個替換為:

if (comp_str(temp[i].name, varray[j].name) == 0) {
    flag = 0;
    break;
}
else
    flag = 1;

您只想在分析了整個字符串后設置標志。 因此,將其傳遞給另一個函數,對返回值起作用,它就可以工作! 通常將您的代碼切成薄片。 更容易采取行動/思考。 (並且還避免在代碼中出現類似varray[j].name[k] != temp[i].name[k] ,這樣的時間長了一點也不varray[j].name[k] != temp[i].name[k] 。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM