全局字符*数组被覆盖

时间:2018-08-02 09:15:45

标签: c arrays

我试图在C中使用全局声明的char *数组来存储一些名称,但是,成功写入正确的值后,整个数组将被最后输入的值覆盖。 我希望能够将char中的stdin个数组存储到char *names[]中,当我运行readNames函数时,一切似乎都很好,但是如果运行printNames,我会注意到数组中的每个空格都被最后一个值覆盖,为什么?

#include <stdio.h>

#define NUM_OF_NAMES 20
#define NAME_SIZE 15

int readNames(int);
int readName(int);
int sortNames();
int printNames();

char* names[NUM_OF_NAMES];
char nameHolder[NAME_SIZE];

int main () {
    readNames(NUM_OF_NAMES);
    printf("\n");
    printNames();
    return 0;
}

int readNames(int qty) {
    for ( int i = 0; i < qty; i++ ) {
        readName(i);
        printf("%s \n", names[i]);
    }
    return 0;
}

int readName() {
    char c;
    for ( int i = 0; i < NAME_SIZE; i++ )
        nameHolder[i] = '\0';
    for ( int i = 0; i < NAME_SIZE; i++ ) {
        c = getchar();
        if ( (c == '\"') || (c == 32) )
            c = getchar();
        if (c == ','){
            names[target] = nameHolder;
            return 0;
        }
        nameHolder[i] = c;
    }
    names[target] = nameHolder;
    return 0;
}

int sortNames() {
    return 0;
}

int printNames() {
    for ( int i = 0; i < NUM_OF_NAMES; i++ ) {
        printf("%s \n", names[i]);
    }
    return 0;
}

输出:

MARY  PATRICIA  LINDA  BARBARA  ELIZABETH  JENNIFER 
MARIA  SUSAN  MARGARET  DOROTHY  LISA  NANCY  KAREN  BETTY  HELEN 
SANDRA  DONNA  CAROL  RUTH  SHARON 

SHARON  SHARON  SHARON  SHARON  SHARON  SHARON  SHARON  SHARON  SHARON
SHARON  SHARON  SHARON  SHARON  SHARON  SHARON  SHARON  SHARON  SHARON
SHARON  SHARON

我尝试通过在每个元素上写入char *字符来初始化15数组,但是结果是相同的,不确定这里发生了什么,还有什么我可以尝试的吗?最好不使用其他库?

2 个答案:

答案 0 :(得分:0)

您在此处声明两个对象:

char* names[NUM_OF_NAMES];
char nameHolder[NAME_SIZE];

第一个是指针数组,第二个是字符数组。

您的代码始终写入第二个数组,然后将第一个数组中的一个指针设置为指向第二个数组。因此最后,所有指针都指向同一个对象nameHolder

一个简单的解决方法是使用2D数组,如下所示:

char names[NUM_OF_NAMES][NAME_SIZE];

然后在阅读内容时直接写到names[i](如果写单个字符,则写成names[i][j]之类的内容。)

您还可以使用malloc()分别分配每个名称。

答案 1 :(得分:0)

好吧,我想您正在尝试通过编写一个小程序来学习C?

首先,您应该(并且我不会是唯一告诉您)避免使用全局变量。它们是一个严重的安全问题,通常显示不良的编码技术。在某些情况下,您无法避免某些全局变量,但是它们很少见,而这并不是其中之一。

您还应该考虑使用头文件(.h)进行声明(没有义务,只是标准要求)。

考虑您的问题:

您有一个缓冲区,用于存储获取的字符(作为名称)。将名称的所有字符都用完后,就可以将该缓冲区的数组分配给指针数组。 但是由于只有1个缓冲区。您正在为每个名称数组分配完全相同的缓冲区地址。 因此,当您读取指针数组时,您正在读取同一指针(即您的缓冲区)的20倍。

为了获得所需的内容,您需要有内存来将缓冲区复制到其中。 通过创建数组names[NUM_OF_NAMES][NAME_SIZE]的数组,或者为获得的每个单词动态分配内存。

对于您的程序,您应该考虑使用强大的C语言库,它将使您能够通过几行来完成您想要实现的工作。