C比较2个字符串变成了内存分配问题
C Comparing 2 strings turned into memory allocation issue
首先让我说,我确实知道有很多标题完全相同的问题,但我没有在其中找到我要找的东西。我试着写了下面的代码,为了错误检查用户的输入,所以他不会给 2 个变量同名。不用说,它失败了,这就是我来这里的原因。在打印我作为字符串比较的字符串时,使用 printf("%s", temp[j].name);
工作正常,character-by-character 打印输出一系列字符,据我所知,这些字符不应该存在。我想知道这可能是怎么回事,如果有办法解决它,那么我实际上可以比较 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] != '[=10=]'; k++){
printf("%c,", temp[i].name[k]);
}
printf("\n");
for (k = 0; temp[i].name[k] != '[=10=]'; 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
的内存已经在其他地方使用了。此错误检查对于我必须做的项目至关重要,因此我将不胜感激能为解决此问题提供的任何帮助。提前致谢,
卢克赛克佩
问题出在你的打印逻辑上。
scanf
函数将用户输入写入数组,后跟一个终止字符“\0”。它不知道你的数组的大小 (20),所以它不会触及它实际上没有写入的数组部分。
而不是这个:
for (k = 0; k < ARRAYLENGTH; k++){
写:
for (k = 0; temp[i].name[k] != '[=11=]'; k++) {
请注意,您无需在此处检查数组末尾的 运行。相反,请确保用户字符串对于您的数组来说不是太大。请参阅 this 了解如何执行此操作。
编辑:此 post 不是要回答原始问题,而是要回答评论中 post 的后续问题。我试图将此合并到之前的答案中,但所有者拒绝了。原来如此。
你的 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] != '[=17=]'; 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;
您只想在分析完整个字符串后设置标志。所以将它传递给另一个函数,根据 return 值进行操作,它就起作用了!通常将您的代码切片。更容易 act/think 上。 (并且还避免在您的代码中出现 varray[j].name[k] != temp[i].name[k]
之类的东西,这种东西很长而且读起来不太舒服。)
首先让我说,我确实知道有很多标题完全相同的问题,但我没有在其中找到我要找的东西。我试着写了下面的代码,为了错误检查用户的输入,所以他不会给 2 个变量同名。不用说,它失败了,这就是我来这里的原因。在打印我作为字符串比较的字符串时,使用 printf("%s", temp[j].name);
工作正常,character-by-character 打印输出一系列字符,据我所知,这些字符不应该存在。我想知道这可能是怎么回事,如果有办法解决它,那么我实际上可以比较 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] != '[=10=]'; k++){
printf("%c,", temp[i].name[k]);
}
printf("\n");
for (k = 0; temp[i].name[k] != '[=10=]'; 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
的内存已经在其他地方使用了。此错误检查对于我必须做的项目至关重要,因此我将不胜感激能为解决此问题提供的任何帮助。提前致谢,
卢克赛克佩
问题出在你的打印逻辑上。
scanf
函数将用户输入写入数组,后跟一个终止字符“\0”。它不知道你的数组的大小 (20),所以它不会触及它实际上没有写入的数组部分。
而不是这个:
for (k = 0; k < ARRAYLENGTH; k++){
写:
for (k = 0; temp[i].name[k] != '[=11=]'; k++) {
请注意,您无需在此处检查数组末尾的 运行。相反,请确保用户字符串对于您的数组来说不是太大。请参阅 this 了解如何执行此操作。
编辑:此 post 不是要回答原始问题,而是要回答评论中 post 的后续问题。我试图将此合并到之前的答案中,但所有者拒绝了。原来如此。
你的 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] != '[=17=]'; 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;
您只想在分析完整个字符串后设置标志。所以将它传递给另一个函数,根据 return 值进行操作,它就起作用了!通常将您的代码切片。更容易 act/think 上。 (并且还避免在您的代码中出现 varray[j].name[k] != temp[i].name[k]
之类的东西,这种东西很长而且读起来不太舒服。)