繁体   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