¿Cómo leer caracteres ilimitados en una variable char*
sin especificar el tamaño?Cómo leer caracteres ilimitados en C
Por ejemplo, supongamos que deseo leer la dirección de un empleado que también puede tomar varias líneas.
¿Cómo leer caracteres ilimitados en una variable char*
sin especificar el tamaño?Cómo leer caracteres ilimitados en C
Por ejemplo, supongamos que deseo leer la dirección de un empleado que también puede tomar varias líneas.
Tienes que comenzar por "adivinar" el tamaño que esperas, luego asigna un buffer tan grande usando malloc
. Si eso resulta demasiado pequeño, usa realloc
para cambiar el tamaño del buffer para que sea un poco más grande. Código de ejemplo:
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++;
}
Esto es justo al lado de la parte superior de mi cabeza, y podría (es decir: probablemente) contienen errores, pero debe darle una buena idea.
@Codeka: debe evitar 'x = realloc (x, newsize);' Si realloc falla, pierde el puntero original y perderá memoria. Dicho esto, una excepción a esta regla es que está bien si su política sobre una falla de alloc es finalizar el proceso. –
Pero, cuidado ... si el realloc falla, ha filtrado el puntero del buffer anterior. Uno debería hacer algo como 'void * sav = ptr; if ((ptr = realloc (ptr, newsiz)) == null) {free (sav); } ' –
Gracias muchachos, eso es correcto. Actualizaré mi ejemplo ... ha pasado un tiempo desde que utilicé C :) –
¿Qué tal si ponemos un buffer de 1KB (o 4KB) en la pila, leyendo hasta encontrar el final de la dirección, y luego asignamos un buffer del tamaño correcto y copiamos los datos en él? Una vez que regrese de la función, el buffer de la pila desaparece y usted solo tiene una sola llamada al malloc
.
¿Qué sucede cuando la dirección es más grande que el buffer 1k o 4k en la pila? – Gabe
@gabe: ¿Cómo se escribe una dirección de 4KB en un sobre? – tomlogic
No conocer el tamaño de una cadena de entrada e intentar leerlo en un búfer de tamaño fijo es la fuente de problemas de seguridad incalculables en el código C. – Gabe
Acabo de responder a Ex7.1, pg 330 de Beginning C, de Ivor Horton, 3ra edición. Tomó un par de semanas para entrenar. Permite la entrada de números flotantes sin especificar de antemano cuántos números ingresará el usuario. Almacena los números en una matriz dinámica y luego imprime los números y el valor promedio. Usando Code :: Blocks con Ubuntu 11.04. Espero eso ayude.
/*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 */
¡Buen intento! Un par de sugerencias de rendimiento: trate de evitar muchos realocos, implican copiar todo lo que le rodea. En su lugar, realceloc por un factor de 2 o 4, y tenga en cuenta tanto el espacio disponible como el espacio utilizado. Además, el promedio puede calcularse en tiempo de ejecución sin presurizar nada. – qdot
Las respuestas a continuación demuestran la mecánica del problema, y te animo a que las estudies Una implementación común es 'getline'. – dmckee
¡Debe comenzar asegurándose de que su hardware tenga memoria ilimitada! – theglauber