【发布时间】:2011-01-31 02:50:08
【问题描述】:
如何在不指定大小的情况下将无限字符读入char* 变量?
例如,假设我想读取可能也需要多行的员工的地址。
【问题讨论】:
-
下面的答案展示了问题的机制,我鼓励您研究它们一种常见的实现是
getline。 -
你必须首先确保你的硬件有无限的内存!
标签: c input dynamic-memory-allocation realloc
如何在不指定大小的情况下将无限字符读入char* 变量?
例如,假设我想读取可能也需要多行的员工的地址。
【问题讨论】:
getline。
标签: c input dynamic-memory-allocation realloc
您必须首先“猜测”您期望的大小,然后使用malloc 分配一个那么大的缓冲区。如果结果太小,您可以使用realloc 将缓冲区大小调整为更大一点。示例代码:
char *buffer;
size_t num_read;
size_t buffer_size;
buffer_size = 100;
buffer = malloc(buffer_size);
num_read = 0;
while (!finished_reading()) {
char c = getchar();
if (num_read >= buffer_size) {
char *new_buffer;
buffer_size *= 2; // try a buffer that's twice as big as before
new_buffer = realloc(buffer, buffer_size);
if (new_buffer == NULL) {
free(buffer);
/* Abort - out of memory */
}
buffer = new_buffer;
}
buffer[num_read] = c;
num_read++;
}
这只是我的想法,可能(阅读:可能)包含错误,但应该给你一个好主意。
【讨论】:
x = realloc(x, newsize); 如果 realloc 失败,你会丢失原始指针并且你会泄漏内存。也就是说,此规则的一个例外是,如果您的分配失败策略是结束进程,则可以。
void *sav=ptr; if((ptr=realloc(ptr,newsiz))==null) { free(sav); }
只需要回答 Ivor Horton 第 3 版的《Beginning C》第 330 页的 Ex7.1。花了几个星期来锻炼。允许输入浮点数,而无需预先指定用户将输入多少个数字。将数字存储在动态数组中,然后打印出数字和平均值。在 Ubuntu 11.04 中使用 Code::Blocks。希望对您有所帮助。
/*realloc_for_averaging_value_of_floats_fri14Sept2012_16:30 */
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
int main(int argc, char ** argv[])
{
float input = 0;
int count=0, n = 0;
float *numbers = NULL;
float *more_numbers;
float sum = 0.0;
while (TRUE)
{
do
{
printf("Enter an floating point value (0 to end): ");
scanf("%f", &input);
count++;
more_numbers = (float*) realloc(numbers, count * sizeof(float));
if ( more_numbers != NULL )
{
numbers = more_numbers;
numbers[count - 1] = input;
}
else
{
free(numbers);
puts("Error (re)allocating memory");
exit(TRUE);
}
} while ( input != 0 );
printf("Numbers entered: ");
while( n < count )
{
printf("%f ", numbers[n]); /* n is always less than count.*/
n++;
}
/*need n++ otherwise loops forever*/
n = 0;
while( n < count )
{
sum += numbers[n]; /*Add numbers together*/
n++;
}
/* Divide sum / count = average.*/
printf("\n Average of floats = %f \n", sum / (count - 1));
}
return 0;
}
/* Success Fri Sept 14 13:29 . That was hard work.*/
/* Always looks simple when working.*/
/* Next step is to use a function to work out the average.*/
/*Anonymous on July 04, 2012*/
/* http://www.careercup.com/question?id=14193663 */
【讨论】:
在堆栈上放置一个 1KB 缓冲区(或 4KB),读取它直到找到地址的结尾,然后分配一个正确大小的缓冲区并将数据复制到它,怎么样?从函数返回后,堆栈缓冲区消失,您只需调用一次 malloc。
【讨论】:
fgets 有一个缓冲区大小参数。标准 C 库中肯定有要避免的函数(如 gets)。使用长度限制函数和固定大小的缓冲区对我来说似乎很安全。