Back to code 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.

This post is not in your language yet; you are seeing it in Spanish. The code is the same.

The problem

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;
}

Why it is written this way

  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.
How to try it

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

Watch out

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.

Adapt it to your case with AI

The button copies this prompt with the code pasted below it. Replace the brackets with your own details and paste it into ChatGPT, Claude, Gemini or Copilot.

The 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].

Example written and reviewed by hand.

Share

Comments

No comments yet. Yours can be the first.

Plain text only, no links. No email is requested. Comments are reviewed before they are published.

Did you adapt it to something of yours?

Tell me what you solved with it, or what it was missing.

Keep trying

More code

See all
Darinel Ortega Online · I reply during the day
Today
Hello. I'm not selling anything here: this is for exchanging knowledge about technology.
Write whatever you like — you can send text, images or documents. Messages reach my console and I reply from there.
You are writing outside working hours. I will read you as soon as the day starts.

An open conversation to share knowledge. Messages reach my console and I reply from there.

Let us book a conversation

Pick the day and time that work for you. Thirty minutes, no sales pitch.

Video call

For a video call, just ask for one here and I'll send you the session link.