如何在c中使用未知数组长度和未知字符串长度生成字符串数组?假设内存足够

如何在c中使用未知数组长度和未知字符串长度生成字符串数组?假设内存足够,c,C,如果我想将字符串数组存储在stdin的C程序中,其数组长度事先未知,并且字符串长度是不固定的或不受限制的。这意味着我不能定义char buf[10][100];在节目中。对于这种情况有什么好的解决方案吗?C标准没有这样的功能,但是POSIX可以满足您的需要。这可能是你想要的,也可能不是,这取决于你计划在什么操作系统上运行它 你只需要做一些类似的事情: char *inf_line = NULL; size_t n = 0; ssize_t input = getline(&inf_lin

如果我想将字符串数组存储在stdin的C程序中,其数组长度事先未知,并且字符串长度是不固定的或不受限制的。这意味着我不能定义char buf[10][100];在节目中。对于这种情况有什么好的解决方案吗?

C标准没有这样的功能,但是POSIX可以满足您的需要。这可能是你想要的,也可能不是,这取决于你计划在什么操作系统上运行它

你只需要做一些类似的事情:

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

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

C标准没有这样的函数,但是POSIX可以满足您的需要。这可能是你想要的,也可能不是,这取决于你计划在什么操作系统上运行它

你只需要做一些类似的事情:

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

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

以下面的代码为例,了解如何读取输入直到达到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时理解输入格式参见以下代码作为示例,说明如何读取输入直到达到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时理解输入格式,请使用动态内存分配。如果替换为“unlimited”使用“未知,但限制为小于可用内存空间”,可能有一个答案。如果您提前知道实际字符串大小,您可以事先分配一个适当大小的数组并读入其中。否则,您可能必须读取固定大小块列表中的输入,并在读取所有输入后分配数组。首先,您需要为计算机配备无限的RAM单元。转到计算机商店,询问一台RAM不受限制的计算机的成本。使用动态内存分配。如果将“不受限制”替换为“未知,但限制为小于可用内存空间”,可能有一个答案。如果您提前知道实际字符串大小,您可以事先分配一个适当大小的数组并读入其中。否则,您可能必须读取固定大小块列表中的输入,并在读取所有输入后分配数组。首先,您需要为计算机配备无限的RAM单元。去电脑商店问问一台内存无限的电脑需要多少钱。为什么要播放
malloc()的结果
?@RoadRunner正如上面第一次分配的代码中所评论的那样,我现在正在使用Visual Studio,它提供了蹩脚的intellisense,混淆了语言,并突出显示未强制分配是一个错误,尽管我知道它不应该发生,是的,这很好。我的UV:)。为什么要强制执行
malloc()的结果
?@RoadRunner正如上面第一次分配的代码中所评论的,我现在正在使用Visual Studio,它提供了糟糕的intellisense,混淆了语言,突出显示未铸造的分配是一个错误,尽管我知道它不应该发生,是的,这很好。我的UV:)。