如何在c中制作一个具有未知数组长度和未知字符串长度的字符串数组?假设记忆足够

时间:2017-02-06 05:26:48

标签: c

如果我想从stdin在C程序中存储字符串数组,其数组长度事先是未知的,字符串长度是不固定的或无限制的。这意味着我无法定义char buf [10] [100];在该计划中。这种情况有什么好的解决方案吗?

2 个答案:

答案 0 :(得分:1)

C标准没有这样的功能,但是getline()是POSIX做你想要的。这可能是您正在寻找的,也可能不是,这取决于您计划在哪个操作系统上运行。

您只需执行以下操作:

char *inf_line = NULL;
size_t n = 0;
ssize_t input = getline(&inf_line, &n, stdin);

或者,您可以尝试在某个循环中使用getchar()填充数组,例如,在使用malloc()到达数组末尾时动态重新分配内存。

答案 1 :(得分:1)

请参阅以下代码作为示例,了解如何在达到EOF之前读取输入(在终端中,尝试 Ctrl-Z Ctrl-D 来模拟EOF,具体取决于在您的操作系统上),通过使用固定大小的块并在读取最后一个块后创建一个完整的字符串。

#define CHUNK_SIZE 4 // testing size
//#define CHUNK_SIZE 1024 // my suggested production size

struct node
{
    char data[CHUNK_SIZE];
    struct node* next;
};

int main()
{
    // will be allocated and filled after reading all input
    char* full_text = NULL;
    // head node
    struct node* start = NULL;
    // iterator node
    struct node* current = NULL;
    // for tail allocation
    struct node** next = &start;
    // count the number of chunks (n-1 full and one partially filled)
    size_t count = 0;
    // size of the last read - will be the count of characters in the partially filled chunk
    size_t last_size;
    // will be initialized to the full text size (without trailing '\0' character)
    size_t full_size;
    while (!feof(stdin))
    {
        // casting malloc result is bad practice, but working with VS here and it's complaining otherwise
        // also, you may want to check the result for NULL values.
        *next = (struct node*)calloc(1, sizeof (struct node));
        last_size = fread_s((*next)->data, CHUNK_SIZE, 1/* sizeof char */, CHUNK_SIZE, stdin);
        next = &((*next)->next);
        ++count;
    }
    // calculate the full size and copy each chunk data into the combined text
    if (count > 0)
    {
        full_size = CHUNK_SIZE * (count - 1) + last_size;
        // one additional character for the null terminator character
        full_text = (char*)malloc(full_size + 1);
        full_text[full_size] = '\0';
        count = 0;
        current = start;
        while (current && current->next)
        {
            memcpy(&full_text[count * CHUNK_SIZE], current->data, CHUNK_SIZE);
            current = current->next;
            ++count;
        }
        if (current)
        {
            memcpy(&full_text[count * CHUNK_SIZE], current->data, last_size);
        }
    }
    else
    {
        full_text = (char*)calloc(1, 1);
    }
    // full_text now contains all text
    // TODO free the node structure

    return 0;
}

旁注:我使用calloc代替malloc,因此我获得零初始化存储空间。

旁注:我使用二进制fread_s而不是fgets,它不会对读取数据进行零终止(否则需要一些不同的处理)并且可能不会很好使用非ASCII输入。因此,在使用此1:1

时,请确保您了解输入格式