[英]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.