我需要創建一個字串陣列,每個字串代表一張西班牙套牌:
#define __USE_MINGW_ANSI_STDIO 1
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char *type[4]= {"copas", "basto", "espada", "oro"};
char *number[10]= {"Uno", "Dos", "Tres", "Cuatro", "Cinco", "Seis", "Siete", "Diez", "Once", "Doce"};
char *deck[40];
int deckIndex= 0;
for (int i = 0; i < 4; i )
{
for (int j = 0; j < 10; j ) {
char card[100] = "";
strcat(card, number[j]);
strcat(card, " de ");
strcat(card, type[i]);
strcat(card, "\n");
deck[deckIndex]= card;
deckIndex ;
}
}
for (int i = 0; i < 40; i )
{
printf("%s\n", deck[i]);
}
return 0;
}
但是,deck[] 的所有條目都指向同一個字串。結果,“Doce de oro”被列印了 40 次。我不明白為什么會發生這種情況,但我推測這是因為 card[] 正在以相同的記憶體方向重新初始化,并覆寫了上一次迭代中已經寫入的內容。如果我是對的,我將不得不分別宣告每個陣列,但我不知道如何在不撰寫 40 個不同陣列的情況下做到這一點。
Tldr:?為什么deck[] 的所有條目都指向同一個位置?我如何解決它?
(順便說一句,對更好的標題的建議表示贊賞)
uj5u.com熱心網友回復:
在 C 中,堆疊上的記憶體是根據作用域分配的。所以是的,你的理論是對的。您正在同一位置重寫。
要修復您的程式,我可以想到兩種可能的解決方案。
- 您可以使用多維陣列。
- 或者您可以使用堆分配記憶體
malloc(但請確保在完成后釋放它)
uj5u.com熱心網友回復:
正如評論中指出的那樣,在這一deck[deckIndex]= card;行中,您將相同的指標1分配給每個deck元素——更糟糕的是,一個指向變數(card陣列)的指標在初始嵌套for回圈結束時不再有效范圍。
要解決此問題,您可以card使用strdup 函式制作字串的副本,并將這些副本的地址分配給deck元素。此外,正如評論中所提到的,您可以card使用對 的單個呼叫來簡化字串的構造sprintf,而不是使用多個strcat呼叫。
您可以這樣做:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char* type[4] = { "copas", "basto", "espada", "oro" };
char* number[10] = { "Uno", "Dos", "Tres", "Cuatro", "Cinco", "Seis", "Siete", "Diez", "Once", "Doce" };
char* deck[40];
int deckIndex = 0;
for (int i = 0; i < 4; i ) {
for (int j = 0; j < 10; j ) {
char card[100] = "";
sprintf(card, "%s de %s", number[j], type[i]);
deck[deckIndex] = strdup(card);
deckIndex ;
}
}
for (int i = 0; i < 40; i ) {
printf("%s\n", deck[i]);
}
// When you're done, be sure to free the allocated memory:
for (int i = 0; i < 40; i ) {
free(deck[i]);
}
return 0;
}
如果您的編譯器不支持該strdup函式(大多數支持,并且它是來自 C23 的 ISO C 標準的一部分),則撰寫自己的函式非常簡單:
char* strdup(const char *src)
{
char* result = malloc(strlen(src) 1); // Add one to make room for the nul terminator
if (result) strcpy(result, src);
return result;
}
1好吧,正式地說,card內部for回圈的每次迭代都會生成一個新陣列,但是選擇這樣做的編譯器效率非常低,而不是簡單地重新使用相同的記憶體 - 這顯然是您的案件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/327477.html
標籤:C
上一篇:即使使用正確的分隔符,strtok也無法正確拆分空格
下一篇:C中的字典,函式作為值
