La manipulación de cadenas en el lenguaje C es una de las habilidades importantes al aprender programación. En particular, la extracción de subcadenas (extracción de subcadenas) se utiliza comúnmente en el procesamiento de datos y la conversión de formatos. En este artículo, explicaremos en detalle los métodos para extraer subcadenas en el lenguaje C, incluyendo el uso de funciones de la biblioteca estándar, la creación de funciones personalizadas, el manejo de caracteres multibyte (japonés), métodos de división de cadenas, etc. También introduciremos ejemplos de aplicación y manejo de errores, así que por favor léanlo hasta el final.
Lo que se puede aprender en este artículo
Al leer este artículo, puede adquirir habilidades como las siguientes.
Conceptos básicos de las cadenas en el lenguaje C y el rol del carácter de terminación ' '
strncpy o strchr , como extracción de subcadenas usando funciones de la biblioteca estándar
Métodos de implementación de manipulación de cadenas usando funciones personalizadas
Procesamiento de cadenas UTF-8 o Shift_JIS considerando caracteres multibyte (japonés)
strtok para métodos de división de cadenas
Métodos para obtener el contenido antes y después de un carácter específico y ejemplos de aplicación
Explicaremos intercalando ejemplos de código para que sea fácil de entender incluso para principiantes.
¿Por qué es importante la extracción de subcadenas en el lenguaje C?
El lenguaje C maneja las cadenas como «arreglos (arreglos de tipo char)», por lo que no se puede obtener subcadenas fácilmente como en otros lenguajes de alto nivel (Python o JavaScript, etc.). Por lo tanto, es importante seleccionar el método adecuado en situaciones como las siguientes.
1. Procesamiento de datos de entrada
Por ejemplo, al analizar datos como logs o archivos CSV, es necesario extraer ítems específicos.
2. Búsqueda de palabras clave específicas
Buscar una palabra clave específica en una cadena y obtener la información antes y después es indispensable para funciones de búsqueda y extracción de datos.
3. Mejora de la seguridad del programa
strncpy Al usar funciones como esta de manera adecuada, se puede prevenir desbordamientos de búfer (escritura de datos que exceden el tamaño del búfer). Esto es importante para evitar riesgos de seguridad.
Estructura de este artículo
En este artículo, procederemos con la explicación en el siguiente flujo.
¿Qué son las cadenas en el lenguaje C? Importancia de los conceptos básicos y el carácter de terminación
Métodos para extraer subcadenas en el lenguaje C [Edición de biblioteca estándar]
Métodos para extraer subcadenas en el lenguaje C [Edición de funciones personalizadas]
Métodos de extracción de cadenas según la codificación de caracteres
Métodos para dividir cadenas en el lenguaje C
Ejemplo de aplicación: Métodos para extraer el contenido antes y después de un carácter específico
Resumen
FAQ
Entonces, empecemos detallando «¿Qué son las cadenas en el lenguaje C? Importancia de los conceptos básicos y el carácter de terminación».
2. ¿Qué son las cadenas en C? Conceptos básicos e importancia del carácter de terminación
2.1 Conceptos básicos de las cadenas en C
Las cadenas son «arrays de char»
En C, las cadenas se tratan como arrays de caracteres (arrays de tipo char). Por ejemplo, el siguiente código es un ejemplo básico de definición e impresión de una cadena.
#include
int main() {
char str[] = "Hello, World!"; // Definir el literal de cadena como un array
printf("%s\n", str); // Imprimir la cadena
return 0;
}
En este código, la cadena "Hello, World!" se almacena como un array de tipo char, y se imprime mediante printf("%s", str);.
Estructura interna de las cadenas
La cadena "Hello" se almacena en memoria de la siguiente manera.
Índice
0
1
2
3
4
5
Carácter
H
e
l
l
o
En C, se agrega automáticamente al final un carácter especial que indica el terminador de la cadena (carácter nulo '\0'), por lo que la longitud de la cadena es «número real de caracteres + 1».
2.2 Importancia del carácter de terminación (carácter nulo '
¿Qué es el carácter nulo?
')
Problemas si no hay carácter nulo
El carácter nulo ('\0') es un carácter especial que indica el final de la cadena. Para manejar correctamente las cadenas en C, es necesario entender la existencia de este carácter nulo.
#include
int main() {
char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; // Especificar explícitamente el carácter de terminación
printf("%s\n", str); // Se muestra correctamente
return 0;
}
En el código anterior, si no hay '\0', no se reconoce el final de "Hello", y puede ocurrir un comportamiento no deseado.
2.3 Cómo definir correctamente las cadenas
De la siguiente manera, si se olvida el carácter de terminación, puede causar un comportamiento anormal en la memoria.
#include
int main() {
char str[5] = {'H', 'e', 'l', 'l', 'o'}; // No incluye el carácter nulo
printf("%s\n", str); // Puede ocurrir un comportamiento inesperado
return 0;
}
Causa del error
printf("%s", str); es continúa imprimiendo caracteres hasta encontrar el carácter nulo '\0'.
Si no hay '\0', es posible que se imprima otro dato en la memoria.
Método 1: Usar literales de cadena
Método 2: Definir el array explícitamente
El método más común para definir cadenas es usar literales de cadena.
char str[] = "Hello";
En este método, el compilador de C agrega automáticamente el carácter nulo '\0', por lo que no se necesita procesamiento especial.
2.4 Cómo verificar el tamaño de la cadena
Si se define manualmente incluyendo '\0', se escribe de la siguiente manera.
char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
Es importante especificar el tamaño de número de caracteres +1 e insertar '\0' al final.
Si se olvida insertar str[5] en '\0', ocurrirá un comportamiento inesperado.
Funcionamiento de strlen
Para obtener la longitud de la cadena (número de caracteres), se usa la función strlen.
#include
#include
int main() {
char str[] = "Hello";
printf("Longitud de la cadena: %lu\n", strlen(str)); // Imprime 5 (sin incluir el carácter nulo)
return 0;
}
2.5 Resumen
strlencuenta el número de caracteres hasta que aparece el carácter nulo '\0'.
sizeof(str) a diferencia, obtiene no el tamaño del array sino «la longitud real de la cadena».
3. Cómo extraer subcadenas en lenguaje C [Edición de biblioteca estándar]
Las cadenas en C se representan con arrays de char.
Dado que el carácter de terminación (carácter nulo '\0') indica el final de la cadena, es necesario incluirlo siempre.
Para obtener la longitud de la cadena, se usa strlen.
Si no se define la cadena de manera adecuada, puede ocurrir un error inesperado.
3.1 Obtención de subcadenas utilizando strncpy
En el lenguaje C, para extraer subcadenas, hay métodos que utilizan la biblioteca estándar. En esta sección, explicamos elmétodo para obtener parcialmente cadenas de texto utilizando funciones de la biblioteca estándar como strncpy y strchr.
Sintaxis básica de strncpy
strncpy es unafunción que copia una parte de la cadena a otro búfer.
n: Número máximo de caracteres a copiar (sin incluir el '\0')
Puntos de atención de strncpy
#include
#include
int main() {
char src[] = "Hello, World!";
char dest[6]; // Búfer para almacenar la subcadena
strncpy(dest, src, 5); // Copiar los primeros 5 caracteres "Hello"
dest[5] = '\0'; // Agregar el carácter nulo manualmente
printf("Subcadena: %s\n", dest); // Imprimir "Hello"
return 0;
}
3.2 Copia de cadenas segura utilizando strncpy_s
Es necesario agregar manualmente el carácter nulo '\0'strncpy copia un máximo de n caracteres, perono agrega automáticamente el '\0', por lo que es necesario agregar explícitamente dest[n] = '\0';.
Prestar atención al desbordamiento de búferSi n es mayor que el tamaño de dest, existe la posibilidad de escribir más allá del búfer.
Sintaxis básica de strncpy_s
strncpy_s es una versión que mejora la seguridad de strncpy y puede prevenir desbordamientos de búfer.
#include
#include
int main() {
char str[] = "Hello, World!";
char *pos = strstr(str, "World"); // Buscar la posición de "World"
if (pos != NULL) {
printf("Subcadena encontrada: %s\n", pos);
} else {
printf("No se encontró la subcadena.\n");
}
return 0;
}
3.5 Resumen
strstr devuelve el puntero del needle encontrado primero.
Si se devuelve NULL, significa que needle no existe en haystack.
4. Cómo extraer subcadenas en C [Edición de funciones personalizadas]
Al usar strncpy, se puede copiar subcadenas de manera segura, pero es necesario agregar manualmente el carácter nulo.
strncpy_s permite especificar destsz, mejorando la seguridad.
Al usar strchr, se puede obtener la subcadena hasta un carácter específico.
Al usar strstr, se puede obtener la posición de una palabra clave específica y extraer a partir de allí.
Al utilizar la biblioteca estándar, se puede implementar el procesamiento de cadenas en lenguaje C de manera simple y segura.
4.1 Ventajas de crear funciones personalizadas
Si se utiliza la biblioteca estándar, es posible extraer subcadenas básicas, pero en algunos casos se requiere un método más flexible. Por lo tanto, en esta sección explicaremos la extracción de subcadenas usando funciones personalizadas.
4.2 Función básica para extraer subcadenas
Con la biblioteca estándar se pueden copiar y buscar subcadenas, pero hay los siguientes problemas.
strncpy no agrega automáticamente el carácter nulo '\0'
strchr o strstr solo permiten búsquedas parciales
Es difícil realizar operaciones de cadenas más flexibles
Por lo tanto, crear funciones personalizadas que se puedan personalizar según usos específicos es efectivo.
Especificaciones de la función
Primero, creamos una función básica que extrae una cadena desde una posición especificada.
Código de implementación
Argumentos
const char *source (cadena original)
int start (posición de inicio)
int length (número de caracteres a extraer)
char *dest (buffer para almacenar la subcadena extraída)
Contenido del procesamiento
start desde length caracteres de la cadena a dest copiar
'\0' agregar automáticamente
Puntos clave
#include
#include
void substring(const char *source, int start, int length, char *dest) {
int i;
for (i = 0; i < length && source[start + i] != '\0'; i++) {
dest[i] = source[start + i];
}
dest[i] = '\0'; // Agregar carácter nulo
}
int main() {
char text[] = "Hello, World!";
char result[10];
substring(text, 7, 5, result); // Extraer "World"
printf("Subcadena: %s\n", result);
return 0;
}
4.3 Obtención dinámica de subcadenas usando malloc
for bucle para copiar los length caracteres especificados.
'\0' al llegar, terminar el bucle.
dest[i] = '\0'; agregar para colocar siempre el carácter nulo al final.
Especificaciones de la función
En la función anterior, es necesario asegurar el tamaño de dest de antemano. Sin embargo, si se puede asegurar el tamaño necesario dinámicamente, se convierte en una función más general.
Código de implementación
Asegurar la memoria necesaria con malloc
start desde length caracteres de subcadena a un nuevo buffer copiar
El llamador debe free
Puntos clave
#include
#include
#include
char *substring_dynamic(const char *source, int start, int length) {
char *dest = (char *)malloc(length + 1); // +1 para el carácter nulo
if (dest == NULL) {
return NULL; // Fallo en la asignación de memoria
}
int i;
for (i = 0; i < length && source[start + i] != '\0'; i++) {
dest[i] = source[start + i];
}
dest[i] = '\0';
return dest;
}
int main() {
char text[] = "Hello, World!";
char *result = substring_dynamic(text, 7, 5);
if (result != NULL) {
printf("Subcadena: %s\n", result);
free(result); // Liberar memoria
} else {
printf("Fallo en la asignación de memoria.\n");
}
return 0;
}
4.4 Compatibilidad con caracteres multibyte (japonés)
malloc para asignar memoria dinámicamente, por lo que no es necesario preocuparse por el tamaño del buffer.
Después del uso, es necesario liberar la memoria con free(result);.
Implementación considerando caracteres multibyte
Al manejar japonés (caracteres multibyte como UTF-8), un carácter no siempre es 1 byte, por lo que una función substring simple no funcionará correctamente.
Código de implementación (compatible con UTF-8)
mbstowcs usar para convertir cadena multibyte a cadena amplia (wchar_t)
setlocale(LC_ALL, ""); para establecer localización y compatibilidad multibyte.
mbstowcs para convertir cadena multibyte a cadena amplia.
wcsncpy para obtener subcadena, luego wcstombs para volver a multibyte.
5. Método de extracción de subcadenas por código de caracteres
Si se crea substring uno mismo, se puede obtener subcadenas de manera flexible.
Usar asignación de memoria dinámica (malloc) permite obtener subcadenas de tamaño variable.
Para manejar caracteres multibyte (japonés), utilizar mbstowcs / wcstombs.
En casos donde strncpy o strchr de la biblioteca estándar son difíciles de usar, crear funciones personalizadas puede hacer el procesamiento de cadenas en C más potente.
5.1 Caso de ASCII (caracteres de 1 byte)
En C, si no se presta atención a las diferencias en los códigos de caracteres, el procesamiento de extracción de cadenas no funcionará correctamente en algunos casos. En particular, al manejar caracteres multibyte como el japonés (UTF-8, Shift_JIS, EUC-JP, etc.), ya que 1 carácter ≠ 1 byte, funciones simples como strncpy o substring no pueden procesarlas adecuadamente. En esta sección, explicamos en detalle el método de extracción de subcadenas por código de caracteres.
Obtención básica de subcadena
Ejemplo de implementación
Los caracteres ASCII son 1 carácter = 1 byte, por lo que strncpy o substring permiten procesarlos fácilmente.
En el caso de caracteres ASCII (solo alfanuméricos), strncpy es suficiente
' ' (carácter nulo) debe agregarse siempre
Características de UTF-8
Método de procesamiento correcto
En UTF-8, el número de bytes por carácter es 1-4 bytes y variable, por lo que usar simplemente strncpy puede cortar en medio de un carácter.
Obtención de subcadena compatible con UTF-8
En C, para procesar UTF-8 de manera segura, se recomienda usar mbstowcs para convertir a cadena ancha (wchar_t) y obtener la subcadena.
5.3 Caso de Shift_JIS (caracteres multibyte)
#include
#include
#include
#include
void substring_utf8(const char *source, int start, int length, char *dest) {
setlocale(LC_ALL, ""); // Configurar el locale
wchar_t wsource[256];
mbstowcs(wsource, source, 256); // Convertir la cadena multibyte a cadena ancha
wchar_t wresult[256];
wcsncpy(wresult, wsource + start, length); // Obtener la subcadena
wresult[length] = L' ';
wcstombs(dest, wresult, 256); // Convertir de nuevo la cadena ancha a multibyte
}
int main() {
char text[] = "¡Hola, mundo!"; // Cadena UTF-8
char result[20];
substring_utf8(text, 5, 3, result); // Obtener "mundo"
printf("Subcadena: %s\n", result);
return 0;
}
Puntos clave
setlocale(LC_ALL, ""); Sin configurar el locale, los caracteres multibyte no se procesan correctamente.
mbstowcs convierte la cadena multibyte a wchar_t y wcsncpy procesa de manera segura.
wcstombs vuelve a convertir a cadena multibyte.
Características de Shift_JIS
Obtención de subcadena compatible con Shift_JIS
En Shift_JIS, 1 carácter es 1 byte o 2 bytes, por lo que strncpy simple causa garabateo de caracteres.
Implementación en Shift_JIS
También en el caso de Shift_JIS se recomienda el método de conversión a cadena ancha para procesar.
5.4 Caso de EUC-JP (caracteres multibyte)
#include
#include
#include
#include
void substring_sjis(const char *source, int start, int length, char *dest) {
setlocale(LC_ALL, "Japanese"); // Configurar el locale para procesar Shift_JIS
wchar_t wsource[256];
mbstowcs(wsource, source, 256);
wchar_t wresult[256];
wcsncpy(wresult, wsource + start, length);
wresult[length] = L' ';
wcstombs(dest, wresult, 256);
}
int main() {
char text[] = "¡Hola, mundo!"; // Cadena Shift_JIS (depende del entorno)
char result[20];
substring_sjis(text, 5, 3, result);
printf("Subcadena: %s\n", result);
return 0;
}
Puntos clave
Para procesar Shift_JIS correctamente, configurar setlocale(LC_ALL, "Japanese"); .
mbstowcs y wcstombs se usan para procesar la cadena de manera segura.
Características de EUC-JP
Obtención de subcadena compatible con EUC-JP
Al igual que Shift_JIS, en EUC-JP el número de bytes por carácter varía, por lo que se necesita procesamiento de conversión utilizando caracteres anchos.
5.5 Resumen
#include
#include
#include
#include
void substring_eucjp(const char *source, int start, int length, char *dest) {
setlocale(LC_ALL, "ja_JP.eucJP"); // Configurar el locale para procesar EUC-JP
wchar_t wsource[256];
mbstowcs(wsource, source, 256);
wchar_t wresult[256];
wcsncpy(wresult, wsource + start, length);
wresult[length] = L' ';
wcstombs(dest, wresult, 256);
}
int main() {
char text[] = "¡Hola, mundo!"; // Cadena EUC-JP (depende del entorno)
char result[20];
substring_eucjp(text, 5, 3, result);
printf("Subcadena: %s\n", result);
return 0;
}
Puntos clave
setlocale(LC_ALL, "ja_JP.eucJP"); configura el locale para EUC-JP.
mbstowcs / wcstombs se usan para procesar correctamente los caracteres multibyte.
6. Cómo dividir cadenas en C
Código de caracteres
Número de bytes
Método de procesamiento recomendado
ASCII
1 byte
strncpy está bien
UTF-8
1-4 bytes
mbstowcs / wcstombs se usan
Shift_JIS
1 o 2 bytes
mbstowcs / wcstombs se usan
EUC-JP
1 o 2 bytes
mbstowcs / wcstombs se usan
Si solo caracteres ASCII, strncpy está bien
En los casos de UTF-8, Shift_JIS, EUC-JP, usar mbstowcs / wcstombs
Configurar setlocale(LC_ALL, "..."); de manera adecuada según el entorno
6.1 División de cadenas usando strtok
El procesamiento de división de cadenas es necesario en muchas situaciones, como el análisis de datos CSV, el procesamiento de argumentos de línea de comandos, el análisis de datos de log, entre otros. En C, hay métodos para usar funciones de la biblioteca estándar como strtok o strtok_r, o para crear funciones personalizadas. En esta sección, explicamos en detalle el método para dividir cadenas con un delimitador específico.
Sintaxis básica
strtok es una función que divide la cadena con el delimitador especificado.
Ejemplo de uso: Dividir cadena con coma ,
char *strtok(char *str, const char *delim);
str: Cadena objetivo de división (especificada en la primera llamada)
delim: Delimitador (se pueden especificar varios)
Valor de retorno: El primer token (la primera parte dividida)
Notas: strtok modifica la cadena original (cambia el delimitador a '\0')
Resultado de ejecución
#include
#include
int main() {
char str[] = "apple,banana,orange,grape"; // Cadena a dividir
char *token = strtok(str, ","); // Obtener el primer token
while (token != NULL) {
printf("Token: %s\n", token);
token = strtok(NULL, ","); // Obtener el siguiente token
}
return 0;
}
Notas sobre strtok
Token: apple
Token: banana
Token: orange
Token: grape
6.2 División de cadenas segura para hilos usando strtok_r
Modifica la cadena original
strtoksobrescribe el delimitador con ‘\0’, por lo que se pierde la cadena original.
No es seguro para hilos
strtokusa una variable estática global internamente, por lo que no es recomendable usarla en entornos multihilo.
Sintaxis básica
strtok_r es la versión segura para hilos de strtok, y guarda el estado en saveptr, por lo que se puede usar de manera segura en entornos multihilo.
str: Cadena objetivo de división (especificada en la primera llamada)
delim: Delimitador (se pueden especificar varios)
saveptr: Puntero que mantiene el estado interno (se actualiza en cada llamada)
Ventajas de strtok_r
#include
#include
int main() {
char str[] = "Hello World from C"; // Cadena a dividir
char *token;
char *saveptr; // Puntero para guardar el estado interno
token = strtok_r(str, " ", &saveptr); // Obtener el primer token
while (token != NULL) {
printf("Token: %s\n", token);
token = strtok_r(NULL, " ", &saveptr); // Obtener el siguiente token
}
return 0;
}
6.3 Dividir cadenas con una función personalizada (sin usar strtok)
Seguro para hilos
Permite procesar múltiples cadenas en paralelo
Especificaciones de la función personalizada
Dado que strtok modifica la cadena original, también es posible crear una función personalizada que divida la cadena sin modificarla.
Código de implementación
Entrada
const char *source (cadena original)
const char delim (delimitador)
char tokens[][50] (arreglo para almacenar las cadenas divididas)
Procesamiento
source se copia para no modificar el original
delim se usa para almacenar los resultados divididos en tokens
Resultado de ejecución
#include
#include
void split_string(const char *source, char delim, char tokens[][50], int *count) {
int i = 0, j = 0, token_index = 0;
while (source[i] != '\0') {
if (source[i] == delim) {
tokens[token_index][j] = '\0';
token_index++;
j = 0;
} else {
tokens[token_index][j] = source[i];
j++;
}
i++;
}
tokens[token_index][j] = '\0';
*count = token_index + 1;
}
int main() {
char text[] = "dog,cat,bird,fish";
char tokens[10][50]; // Puede almacenar hasta 10 palabras
int count;
split_string(text, ',', tokens, &count);
for (int i = 0; i < count; i++) {
printf("Token: %s\n", tokens[i]);
}
return 0;
}
Puntos clave
Token: dog
Token: cat
Token: bird
Token: fish
6.4 Aplicaciones de la división de cadenas (procesamiento de datos CSV)
source se copia y se procesa sin modificar el original.
tokens almacena los resultados divididos y mantiene la cadena original.
Ejemplo de análisis de datos CSV
Los datos CSV (separados por comas) se pueden analizar usando strtok.
Resultado de ejecución
#include
#include
int main() {
char csv[] = "Alice,24,Female\nBob,30,Male\nCharlie,28,Male"; // Datos CSV
char *line = strtok(csv, "\n"); // Procesar línea por línea
while (line != NULL) {
char *name = strtok(line, ",");
char *age = strtok(NULL, ",");
char *gender = strtok(NULL, ",");
printf("Nombre: %s, Edad: %s, Género: %s\n", name, age, gender);
line = strtok(NULL, "\n");
}
return 0;
}
6.5 Resumen
Nombre: Alice, Edad: 24, Género: Female
Nombre: Bob, Edad: 30, Género: Male
Nombre: Charlie, Edad: 28, Género: Male
Conclusión
Método
Ventajas
Desventajas
strtok
Permite dividir fácilmente
Modifica la cadena original
strtok_r
Seguro para hilos
Uso un poco más complejo
Función personalizada
No modifica la cadena original
El código se alarga
Análisis CSV
Útil para procesamiento de datos
Prestar atención a las limitaciones de strtok
7. Ejemplo de aplicación: Cómo extraer antes y después de un carácter específico
Para divisiones simples, usa strtok
Para multihilo, usa strtok_r
Si no quieres modificar el original, usa una función personalizada
También se puede aplicar al análisis de datos CSV
En la siguiente sección, explicamos en detalle «Ejemplo de aplicación: Cómo extraer antes y después de un carácter específico».
7.1 Usar strchr para obtener la cadena antes de un carácter específico
En el procesamiento de cadenas, a menudo es necesario realizar operaciones para extraer antes y después de un carácter o palabra clave específico. Por ejemplo, se pueden considerar casos como los siguientes.
Obtener solo la parte de dominio de una URL
Extraer el nombre de archivo de una ruta de archivo
Obtener la cadena antes y después de una etiqueta o símbolo específico
En C, se puede realizar este procesamiento utilizando strchr o strstr . Además, si se necesita un procesamiento más flexible, crear una función personalizada también es efectivo.
Sintaxis básica
Usando strchr , se puede identificar la posición de un carácter específico (el primero encontrado).
Ejemplo de uso: Obtener el nombre de archivo de una ruta de archivo
char *strchr(const char *str, int c);
str: Cadena de búsqueda
c: Carácter a buscar (tipo char )
strchr devuelve la dirección si encuentra c .
Resultado de ejecución
#include
#include
void get_filename(const char *path, char *filename) {
char *pos = strrchr(path, '/'); // Buscar la última '/'
if (pos != NULL) {
strcpy(filename, pos + 1); // Copiar desde la posición siguiente a '/'
} else {
strcpy(filename, path); // Si no hay '/', copiar tal como está
}
}
int main() {
char path[] = "/home/user/documents/report.txt";
char filename[50];
get_filename(path, filename);
printf("Nombre del archivo: %s\n", filename);
return 0;
}
Puntos clave
Nombre del archivo: report.txt
7.2 Usar strstr para obtener la cadena después de una palabra clave específica
strrchr permite obtener la posición del carácter específico (/ ) que aparece por última vez.
pos + 1 copia la cadena siguiente a la barra diagonal, lo que permite obtener solo el nombre del archivo.
Sintaxis básica
Usando strstr , se puede buscar una cadena específica (palabra clave) y obtener la cadena desde esa posición en adelante.
strstr devuelve la dirección de la posición si encuentra needle .
Resultado de ejecución
#include
#include
void get_domain(const char *url, char *domain) {
char *pos = strstr(url, "://"); // Buscar la posición de "://"
if (pos != NULL) {
strcpy(domain, pos + 3); // Copiar desde después de "://"
} else {
strcpy(domain, url); // Si no hay "://", copiar tal como está
}
}
int main() {
char url[] = "https://www.example.com/page.html";
char domain[50];
get_domain(url, domain);
printf("Parte de dominio: %s\n", domain);
return 0;
}
Puntos clave
Parte de dominio: www.example.com/page.html
7.3 Usar strchr para dividir las partes antes y después de un carácter específico
strstr se usa para obtener desde "https://" o "http://" la parte posterior a "//" .
pos + 3 copia desde después de :// .
Ejemplo de uso: Separar nombre de usuario y dominio de una dirección de correo electrónico
Explotando strchr , se puede obtener dividiendo la cadena antes y después de un carácter específico.
Resultado de ejecución
#include
#include
void split_email(const char *email, char *username, char *domain) {
char *pos = strchr(email, '@'); // Buscar la posición de '@'
if (pos != NULL) {
strncpy(username, email, pos - email); // Copiar antes de '@'
username[pos - email] = '\0'; // Agregar carácter nulo
strcpy(domain, pos + 1); // Copiar la parte después de '@'
}
}
int main() {
char email[] = "user@example.com";
char username[50], domain[50];
split_email(email, username, domain);
printf("Nombre de usuario: %s\n", username);
printf("Dominio: %s\n", domain);
return 0;
}
Puntos clave
Nombre de usuario: user
Dominio: example.com
7.4 Aplicación: Extraer un atributo específico dentro de una etiqueta HTML
strchr busca la posición de '@' .
strncpycopia la parte antes de '@' y agrega el carácter nulo.
strcpycopia la parte después de '@'.
Ejemplo de uso: Obtener la URL de <a href="URL">
Para obtener un atributo específico de una etiqueta HTML, también se puede explotar strstr .
Resultado de ejecución
#include
#include
void get_href(const char *html, char *url) {
char *start = strstr(html, "href=\""); // Buscar la posición de href="
if (start != NULL) {
start += 6; // Mover después de href="
char *end = strchr(start, '"'); // Buscar la siguiente "
if (end != NULL) {
strncpy(url, start, end - start);
url[end - start] = '\0'; // Agregar carácter nulo
}
}
}
int main() {
char html[] = "Click Here";
char url[100];
get_href(html, url);
printf("URL extraída: %s\n", url);
return 0;
}
Puntos clave
URL extraída: https://example.com
7.5 Resumen
strstr busca la posición de "href="" y se mueve 6 caracteres.
strchr busca la posición de " (comilla) y determina el rango.
Conclusión
Contenido del procesamiento
Función utilizada
Ventajas
Obtener antes de un carácter específico
strchr / strrchr
Simple y rápido
Obtener después de un carácter específico
strstr
Posible búsqueda de palabras clave
Dividir antes y después de un carácter específico
strchr + strncpy
Útil para división de nombre de usuario y dominio, etc.
Obtención de atributos de etiquetas HTML
strstr + strchr
Aplicables a web scraping
8. Resumen
Explotando strchr o strstr , se puede obtener fácilmente antes y después de un carácter o palabra clave específico.
Útil en muchos escenarios, como procesamiento de rutas de archivos, análisis de URL y división de direcciones de correo electrónico.
Aplicable también a procesamientos avanzados como web scraping.
8.1 Repaso del artículo
En este artículo, hemos explicado en detalle los métodos para extraer subcadenas en el lenguaje C, desde lo básico hasta lo avanzado. Aquí, repasaremos los puntos clave de cada sección y organizaremos los métodos óptimos según el uso.
8.2 Métodos óptimos según el uso
Sección
Contenido
Puntos clave
Conceptos básicos de cadenas en C
En C, las cadenas se manejan como arrays de char, y el carácter de terminación '\0' es importante
Al manejar cadenas, no olvidar el terminador nulo
Extracción con la biblioteca estándar
Aprovechar strncpy, strchr, etc.
Con strncpy, es necesario agregar manualmente el terminador nulo
Extracción con funciones personalizadas
Crear una función substring flexible
Usar malloc permite obtener subcadenas de longitud variable
Procesamiento según la codificación de caracteres
Métodos de compatibilidad con UTF-8, Shift_JIS, EUC-JP
Usar mbstowcs / wcstombs para convertir a caracteres amplios es seguro
Métodos para dividir cadenas
División con strtok, strtok_r o funciones personalizadas
Con strtok, se modifica la cadena original, así que tener cuidado
Extracción antes y después de un carácter específico
Obtención de datos con strchr, strstr
Se puede aplicar a obtención de nombres de archivos, análisis de URL, análisis de HTML
3. Obtención antes y después de un carácter específico
Casos de uso
Método óptimo
Quiero dividir la cadena de manera simple
strtok
Quiero una división thread-safe
strtok_r
Quiero dividir sin modificar la cadena original
Función personalizada (split_string())
8.3 Precauciones en el procesamiento de cadenas en C
Casos de uso
Método óptimo
Obtener el nombre de archivo de una ruta
strrchr(path, '/')
Obtener la parte de dominio de una URL
strstr(url, "://")
Separar nombre de usuario y dominio de una dirección de correo
strchr(email, '@')
Obtener valores de atributos de etiquetas HTML
strstr(tag, "href=\"") + strchr(tag, '"')
1. Gestionar exhaustivamente el terminador nulo '
Ejemplo de copia de cadena segura
'
2. Prestar atención a desbordamientos de búfer
En el procesamiento de cadenas en C, gestionar adecuadamente el carácter de terminación '\0' es lo más importante. Especialmente al usar strncpy o strchr, tenga cuidado de agregar manualmente el carácter nulo.
3. Para el procesamiento de caracteres multibyte, usar mbstowcs
En las operaciones de cadenas en C, es necesario implementar con precaución para no acceder fuera del rango del array. Especialmente al usar strncpy, es importante controlar el número de bytes a copiar. Ejemplo de copia de cadena segura
Al manejar caracteres multibyte como UTF-8 o Shift_JIS, funciones como strncpy o strlen no funcionan correctamente. Por lo tanto, al manejar caracteres multibyte, se recomienda convertir una vez a cadenas amplias con mbstowcs y procesar adecuadamente.
#include
#include
#include
int main() {
setlocale(LC_ALL, ""); // Establecer la localización
char text[] = "¡Hola, mundo!"; // UTF-8
wchar_t wtext[256];
mbstowcs(wtext, text, 256); // Convertir a cadena amplia
printf("Cadena amplia después de la conversión: %ls\n", wtext);
return 0;
}
Temas para profundizar el aprendizaje
En el procesamiento de cadenas, es importante calcular de antemano el tamaño de memoria necesario y prevenir desbordamientos de búfer. Especialmente al asignar memoria dinámica con malloc, asegúrese de conocer con precisión su tamaño.
8.5 Resumen
El procesamiento de cadenas en C es una habilidad importante para mejorar la seguridad y legibilidad del programa. Basándose en el contenido introducido en este artículo, aprender los siguientes temas permitirá un procesamiento de cadenas más avanzado.
Temas para profundizar el aprendizaje
Expresiones regulares (regex) (posible con bibliotecas externas de C)
Operaciones de archivos (procesamiento de cadenas con fgets, fscanf)
Gestión de memoria (procesamiento dinámico de cadenas con malloc, realloc)
Análisis de datos (métodos de análisis de JSON, XML)
8.5 Resumen
Las cadenas en C se gestionan con arrays de char, por lo que el manejo del carácter de terminación '\0' es importante
Para extraer subcadenas, usar strncpy, substring(), malloc
Para dividir cadenas, aprovechar strtok / strtok_r / funciones personalizadas
Para obtener antes y después de un carácter específico, aprovechar strchr, strstr
Para manejar caracteres multibyte (japonés), utilizar mbstowcs
Tener en cuenta un procesamiento seguro de cadenas y prestar atención a desbordamientos de búfer
Al utilizar el contenido de este artículo, será posible realizar un procesamiento práctico de cadenas en C. Una vez comprendidas las funciones básicas, desafíese a crear funciones personalizadas y procesamiento avanzado para poder escribir código más eficiente.