HOWTO · C

Comprobar si una cadena contiene una subcadena en C

Este artículo muestra cómo comprobar si una cadena contiene una subcadena en C

En esta página

Para comprobar si una cadena de C terminada en nulo contiene una subcadena exacta y distingue entre mayúsculas y minúsculas, llama a strstr desde <string.h>. La función devuelve un puntero a la primera coincidencia o NULL si no encuentra ninguna. Los tres ejemplos se ejecutaron y mostraron Substring found.; ese texto de salida se conserva en inglés.

Comprobar si una cadena contiene una subcadena con strstr

Pasa la cadena completa como primer argumento y el texto que quieres buscar como segundo. Comprueba directamente el puntero devuelto; no lo imprimas como una dirección, ya que su valor depende del proceso. La función strstr está declarada en la cabecera estándar de C <string.h> y compara los caracteres exactamente, incluidas las mayúsculas y minúsculas.

Este programa busca welcome en una frase e imprime un mensaje estable tanto si encuentra la subcadena como si no. La cadena que muestra el ejemplo se conserva en inglés.

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

int main(void) {
    const char *text = "Hello, welcome to C.";
    const char *needle = "welcome";

    if (strstr(text, needle) != NULL) {
        puts("Substring found.");
    } else {
        puts("Substring not found.");
    }
    return 0;
}
Substring found.

El puntero devuelto señala el primer carácter coincidente de text, así que puedes usarlo para inspeccionar la cadena o continuar desde esa posición. Un puntero distinto de nulo indica que hay una coincidencia. Si el texto que buscas es "", strstr devuelve el inicio de text; ten en cuenta este comportamiento estándar si, en tu aplicación, una búsqueda vacía no debe contar como coincidencia.

Buscar una subcadena con un bucle

Una búsqueda manual permite mostrar explícitamente cómo se comparan los caracteres o añadir un comportamiento específico para la aplicación. La función siguiente recibe dos cadenas terminadas en nulo y distintas de NULL; devuelve 1 si encuentra el texto buscado y 0 en caso contrario. Comprueba las longitudes antes de restarlas para evitar un desbordamiento por defecto de un entero sin signo cuando el texto buscado supera la longitud de la entrada. Considera que un texto de búsqueda vacío coincide, igual que strstr.

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

int contains_substring(const char *text, const char *needle) {
    size_t text_len = strlen(text);
    size_t needle_len = strlen(needle);

    if (needle_len == 0) {
        return 1;
    }
    if (needle_len > text_len) {
        return 0;
    }

    for (size_t i = 0; i <= text_len - needle_len; ++i) {
        size_t j = 0;
        while (j < needle_len && text[i + j] == needle[j]) {
            ++j;
        }
        if (j == needle_len) {
            return 1;
        }
    }
    return 0;
}

int main(void) {
    const char *text = "Hello, welcome to C.";
    const char *needle = "welcome";

    puts(contains_substring(text, needle)
             ? "Substring found."
             : "Substring not found.");
    return 0;
}
Substring found.

El bucle externo prueba cada posición inicial en la que cabe el texto buscado completo. El bucle interno avanza mientras coinciden los caracteres correspondientes. Si llega al final del texto buscado, la función ha encontrado una coincidencia completa. Este método sencillo resulta útil para aprender o adaptar la comparación; para las búsquedas exactas habituales, prefiere la función de la biblioteca estándar, salvo que tengas un motivo para mantener tu propio código de búsqueda.

Comprobar si una cadena contiene una subcadena sin distinguir mayúsculas y minúsculas

La biblioteca estándar de C no define una función para buscar subcadenas sin distinguir entre mayúsculas y minúsculas. En sistemas GNU, strcasestr busca sin tener en cuenta esas diferencias y está disponible como extensión de GNU. Define _GNU_SOURCE antes de incluir las cabeceras para solicitar su declaración en los sistemas que usan esta macro de selección de funciones. No forma parte del C estándar portable, así que comprueba que la plataforma de destino la proporciona antes de depender de ella.

Este ejemplo completo usa texto ASCII y muestra la llamada específica de GNU. Imprime Substring found.; el texto mostrado se conserva en inglés.

#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>

int main(void) {
    const char *text = "Hello, Welcome to C.";
    const char *needle = "welcome";

    if (strcasestr(text, needle) != NULL) {
        puts("Substring found.");
    } else {
        puts("Substring not found.");
    }
    return 0;
}
Substring found.

Para escribir código portable, implementa la comparación sin distinguir mayúsculas y minúsculas con una política de caracteres explícita, en lugar de modificar las cadenas de entrada sin advertirlo. La función tolower puede servir para texto tratado como bytes, pero su argumento debe ser EOF o un valor representable como unsigned char, y su comportamiento depende de la configuración regional de C activa. Por sí solo, este método no aplica el plegado de mayúsculas y minúsculas de Unicode. Elige una biblioteca y una política de texto adecuadas para los datos que necesite procesar tu programa.

Tratar los casos límite y elegir un método

Tanto strstr como el bucle anterior buscan en cadenas terminadas en nulo y comparan secuencias exactas de caracteres. Si la aguja es más larga que el texto, no puede haber coincidencia. Si la aguja está vacía, strstr informa de una coincidencia al principio, y la implementación del bucle anterior sigue la misma convención; añade una comprobación explícita si tu aplicación necesita otra regla. El bucle requiere punteros distintos de NULL, igual que las funciones de cadenas estándar requieren argumentos de cadena válidos.

strstr devuelve la primera aparición. Para encontrar las siguientes, continúa la búsqueda desde la coincidencia anterior más la longitud de la aguja, y asegúrate de que la aguja no esté vacía para que la búsqueda avance. Si importan las coincidencias solapadas, avanza un carácter desde la coincidencia anterior. La elección depende de si las apariciones pueden compartir caracteres.

Usa strstr para la comprobación habitual, exacta y sensible a mayúsculas y minúsculas: es concisa y forma parte del C estándar. Recurre a un bucle manual si necesitas explicar o personalizar la comparación, y documenta sus supuestos sobre las entradas. Usa strcasestr solo si está disponible la extensión de GNU y su comportamiento con bytes y configuración regional se ajusta al texto. strpbrk no sirve como alternativa para buscar una subcadena exacta: comprueba si aparece en la entrada cualquier carácter de un conjunto, lo que responde a una pregunta distinta.