How to read unlimited characters into a char*
variable without specifying the size?
For example, say I want to read the address of an employee that may also take multiple lines.
How to read unlimited characters into a char*
variable without specifying the size?
For example, say I want to read the address of an employee that may also take multiple lines.
You have to start by "guessing" the size that you expect, then allocate a buffer that big using malloc
. If that turns out to be too small, you use realloc
to resize the buffer to be a bit bigger. Sample code:
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++;
}
This is just off the top of my head, and might (read: will probably) contain errors, but should give you a good idea.
x = realloc(x, newsize);
If realloc fails, you lose the original pointer and you'll leak memory. That said, one exception to this rule is it's okay if your policy on an alloc failure is to end the process. –
Spates void *sav=ptr; if((ptr=realloc(ptr,newsiz))==null) { free(sav); }
–
Ripen realloc(buffer, num_read);
call to trim the allocated buffer to the exact size required. –
Nonlegal Abort - out of memory
it should say return error code
. –
Smoothen new_buffer
is at the start of a compound statement, so it is completely portable to all versions of standard C. –
Nonlegal strlen()
for that purpose, you need to use a variable to keep track of the currently allocated size (like the buffer_size
in this answer). –
Nonlegal Just had to answer Ex7.1, pg 330 of Beginning C, by Ivor Horton, 3rd edition. Took a couple of weeks to work out. Allows input of floating numbers without specifying in advance how many numbers the user will enter. Stores the numbers in a dynamic array, and then prints out the numbers, and the average value. Using Code::Blocks with Ubuntu 11.04. Hope it helps.
/*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 */
How about just putting a 1KB buffer (or 4KB) on the stack, reading into that until you find the end of the address, and then allocate a buffer of the correct size and copy the data to it? Once you return from the function, the stack buffer goes away and you only have a single call to malloc
.
fgets
has a parameter for buffer size. There are definitely functions in the Standard C Library to avoid (like gets
). Using length-limited functions and fixed-size buffers seems pretty safe to me. –
Clavicorn © 2022 - 2024 — McMap. All rights reserved.
getline
. – Anzovin