我想在指针数组中写几个字符串(名称)。我编写了一个代码,我认为逻辑上会这样做,但由于某种原因,它只打印最后一个字符串。有什么可以解决这个问题?
#include <stdio.h>
#include <stdlib.h>
#define MAX 50
int jatekosell(char* s) {
int n, ok = 1;
n = atoi(s);
if(n<3 || n > 15)
{
printf("Nem jo! 3 es 15 koze kell essen!");
getline(s, MAX);
ok = 0;
}
return ok;
}
int getline(char *s, int n);
void main() {
char amount[MAX];
char name[MAX];
char *names[MAX];
int number, i, j;
printf("Number of players between 3 and 15: ");
getline(amount, MAX);
while(!jatekosell(amount));
number = atoi(amount);
for(i = 0; i < number; i++)
{
printf("Type the %d. name: ", i+1);
getline(name, MAX);
names[i] = name;
}
for(i = 0; i < number; i++)
{
printf("The names: %s\n", names[i]);
}
getchar();
}
int getline(char *s, int n){
int c;
char *t=s;
while(n-- > 0 && (c=getchar())!=EOF&&c!='\n') *t++ = c;
*t='\0';
while(c!=EOF&&c!='\n') c=getchar();
return(t-s);
}
答案 0 :(得分:0)
您将相同的内存位置(name
变量)存储到每个names
数组项中。您可以在打印时将%s
更改为%p
(以显示name[i]
的内存地址)。
您需要将names[i] = name
的内容复制到name
,而不只是分配names[i]
。
答案 1 :(得分:0)
您已将getline()
数据的单个缓冲区声明为char name[MAX];
。
您在那里读取数据,然后使用names[i] = name;
“将其放入数组中”。
问题是数组中的每个元素都指向同一个缓冲区,每个连续的getline()
只会覆盖该缓冲区的内容。
您可以通过将names[i] = name;
替换为names[i] = strdup(name);
来解决此问题。strdup()
函数将字符串复制到动态分配的缓冲区中。请注意,您现在负责在不再需要时释放缓冲区(通过free()
)。
另一个解决方案是将char *names[MAX];
替换为char names[MAX][MAX];
(以预先分配所有缓冲区)和strcpy()
替换到下一个位置,但这可能非常浪费内存。
答案 2 :(得分:0)
这一行
names[i] = name;
错了。您需要使用memcpy,或者每次只覆盖最后一个字符串。你还需要为你收到的字符串分配空间,即MAX == 10;
char *names[10];
正在为字符串分配一个包含10个指针的数组,即分配时没有字符串空间。
char names[10][MAX];
这为您提供了一个指针数组,每个指针都可以包含MAX字符。或者你需要在使用之前将它们malloc,即
names[i] = calloc(1, MAX);
size_t name_len = strlen(name);
assert(name_len < MAX);
memcpy(names[i], name, name_len);
names[i][str_len] = '\0';// Null terminate string