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