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