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