Voltar ao 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.

Este post ainda não está no seu idioma; você o vê em espanhol. O código é o mesmo.

O 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 que está escrito assim

  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.
Como testar

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

Atenção

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.

Adapte ao seu caso com IA

O botão copia este prompt com o código colado abaixo. Substitua os colchetes pelo que é seu e cole no ChatGPT, Claude, Gemini ou Copilot.

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

Exemplo escrito e revisado à mão.

Compartilhar

Comentários

Ainda não há comentários. O primeiro pode ser o seu.

Apenas texto, sem links. Não pedimos e-mail. Os comentários são revisados antes de serem publicados.

Adaptou para algo seu?

Me conte o que resolveu com isto, ou o que faltou.

Continue testando

Mais código

Ver todos
Darinel Ortega Online · respondo ao longo do dia
Hoje
Olá. Aqui eu não vendo nada: isto é para trocar conhecimento sobre tecnologia.
Escreva o que quiser — pode mandar texto, imagens ou documentos. As mensagens chegam ao meu console e eu respondo por lá.
Você está escrevendo fora do horário. Eu leio assim que o dia começar.

Conversa aberta para compartilhar conhecimento. As mensagens chegam ao meu console e eu respondo por lá.

Vamos marcar uma conversa

Escolha o dia e a hora que funcionem para você. Trinta minutos, sem discurso comercial.

Videochamada

Para uma videochamada, peça por aqui que eu te mando o link da sessão.