用getline将字符串读入指针数组(C)

时间:2016-03-17 17:39:54

标签: c arrays string pointers

我想在指针数组中写几个字符串(名称)。我编写了一个代码,我认为逻辑上会这样做,但由于某种原因,它只打印最后一个字符串。有什么可以解决这个问题?

#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); 
}

3 个答案:

答案 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