Volver al código C

Buscar una palabra en un archivo sin desbordar el búfer

Lectura línea por línea con fgets, que nunca escribe fuera del espacio reservado, y códigos de salida que otro programa puede usar.

El problema

Leer texto en C con las funciones equivocadas es el origen clásico de los desbordamientos. Hay que leer un archivo de cualquier tamaño con un búfer fijo y sin riesgo.

C
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc < 3) { fprintf(stderr, "Uso: %s archivo palabra\n", argv[0]); return 1; }

    FILE *f = fopen(argv[1], "r");
    if (!f) { perror(argv[1]); return 1; }

    char linea[1024];
    long n = 0, hallazgos = 0;
    while (fgets(linea, sizeof linea, f)) {      /* nunca escribe fuera del búfer */
        n++;
        if (strstr(linea, argv[2])) {
            printf("%ld: %s", n, linea);
            hallazgos++;
        }
    }
    fclose(f);
    printf("\n%ld coincidencias en %ld líneas\n", hallazgos, n);
    return hallazgos ? 0 : 2;
}

Por qué está escrito así

  1. fgets recibe el tamaño del búfer y se detiene ahí: es la diferencia con gets, que no lo sabe y por eso fue eliminada del lenguaje.
  2. sizeof linea le pasa el tamaño real; si mañana cambia el 1024, el resto sigue bien.
  3. perror imprime el motivo del sistema ("No such file", "Permission denied") sin que haya que adivinarlo.
  4. El código de salida distingue tres casos: encontró, no encontró, o hubo un error de uso.
Cómo probarlo

Guardalo como buscar.c y corré: cc -Wall -o buscar buscar.c && ./buscar buscar.c fgets

Ojo con esto

Una línea de más de 1023 caracteres se lee en dos pedazos: se cuenta como dos líneas y una palabra partida justo en el corte no se encuentra. Para líneas arbitrarias está getline.

Adaptalo a tu caso con IA

El botón copia este prompt con el código pegado debajo. Reemplazá los corchetes con lo tuyo y pegalo en ChatGPT, Claude, Gemini o Copilot.

El prompt
Tengo este buscador de texto en C con fgets. Adaptalo para que maneje líneas de cualquier largo con getline, acepte la opción -i para ignorar mayúsculas y -c para mostrar solo la cantidad, y libere toda la memoria. Compilá mentalmente con -Wall -Wextra y decime si quedaría algún aviso. Estándar [C99 o C11], sistema [LINUX, MACOS].

Ejemplo escrito y revisado a mano.

Compartir

Comentarios

Todavía no hay comentarios. El primero puede ser el tuyo.

Solo texto, sin enlaces. No se pide correo. Los comentarios se revisan antes de publicarse.

¿Lo adaptaste a algo tuyo?

Contame qué resolviste con esto, o qué le faltó.

Seguí probando

Más código

Ver todos
Darinel Ortega En línea · respondo durante el día
Hoy
Hola. Acá no vendo nada: esto es para intercambiar conocimiento sobre tecnología.
Escribime lo que quieras — podés mandar texto, imágenes o documentos. Los mensajes llegan a mi consola y te respondo desde ahí.
Estás escribiendo fuera de horario. Te leo apenas empiece el día.

Conversación abierta para compartir conocimiento. Los mensajes llegan a mi consola y respondo desde ahí.

Agendemos una conversación

Elegí el día y la hora que te sirvan. Son treinta minutos, sin agenda comercial.

Videollamada

Para una videollamada, pedila por acá y te paso el enlace de la sesión.