Strings en C: strrev, strcmp y strcat explicados
Clase 9 de 12 • Curso de Funciones en C
Contenido del curso
Clase 9 de 12 • Curso de Funciones en C
Contenido del curso
Juan Sebastian Ortiz Santacoloma
Juan Andrés Cabrera Mendoza
Yerson Steven Rojas Barragan
Jesús Ignacio García Fernández
Juan Andrés Cabrera Mendoza
Francisco de Castro
Hugo Enrique Avelino Santos
RICARDO WILLIAM CABANILLAS CARDENAS
bior Melgar Luján
Valeria Vanesa Zalazar
Carlos Nassif Trejo Garcia
Leonardo Véliz
Jesús Ignacio García Fernández
Ariel Ezequiel Biazzo Genua
Luis Gabriel Delgado Sanchez
Dan Yael Sajarópulos Verdugo
Ariel Ezequiel Biazzo Genua
Eban Sayago Melián
CRISTIAN BARBERO PÉREZ
Irving Juárez
Leonardo Véliz
Matías Arriola
Erick Jiménez del Río
Jorge Hernández
Juan Francisco
Gabriel Obregón
Marcelo Gaston Duarte
David Acosta
Remberto Alvaro Molina Colodro
Felipe Toro C
Henry Santiago Mora mancera
Jonathan Sanchez
Leonardo Véliz
FABIAN PEREZ
Aparentemente la funcion strrev no se puede usar si usas linux. Segun lo que lei en este caso tendrias que definir tu funcion para reversar caracteres. El codigo se veria asi:
#include <stdio.h> #include <string.h> void reverse(char [], int, int); int main() { char string1[60]; //Cadena de caracteres de 60 int size; printf("Escribe una frase genial: \n"); gets(string1); // Este es especifico para strings size = strlen(string1); reverse(string1, 0, size - 1); // string reverse printf("El string al reves es: %s \n", string1); return 0; } void reverse(char str1[], int index, int size) { char temp; temp = str1[index]; str1[index] = str1[size - index]; str1[size - index] = temp; if (index == size / 2) { return; } reverse(str1, index + 1, size); }
buen dato
gracias!!!
Si tienes linux o el WSL en windows + librerias de C, puedes consultar la ayuda para ver más información de las funciones.
Ejemplo: man strcmp
STRCMP(3) Linux Programmer's Manual STRCMP(3) NAME strcmp, strncmp - compare two strings SYNOPSIS #include <string.h> int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); DESCRIPTION The strcmp() function compares the two strings s1 and s2. It returns an integer less than, equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater than s2. The strncmp() function is similar, except it compares only the first (at most) n bytes of s1 and s2. RETURN VALUE The strcmp() and strncmp() functions return an integer less than, equal to, or greater than zero if s1 (or the first n bytes thereof) is found, respectively, to be less than, to match, or be greater than s2. ATTRIBUTES For an explanation of the terms used in this section, see attributes(7). ┌────────────────────┬───────────────┬─────────┐ │Interface │ Attribute │ Value │ ├────────────────────┼───────────────┼─────────┤ │strcmp(), strncmp() │ Thread safety │ MT-Safe │ └────────────────────┴───────────────┴─────────┘ CONFORMING TO POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD. SEE ALSO bcmp(3), memcmp(3), strcasecmp(3), strcoll(3), string(3), strncasecmp(3), strverscmp(3), wcscmp(3), wcsncmp(3) COLOPHON This page is part of release 4.15 of the Linux man-pages project. A description of the project, information about reporting bugs, and the latest version of this page, can be found at https://www.kernel.org/doc/man-pages/.
buen dato amigo
strrev no esta para el compilador gcc en Linux por lo tanto lo que encontre es que se tiene que hacer la función:
char *strrev(char *str){ char c, *front, *back; if(!str || !*str) return str; for(front=str,back=str+strlen(str)-1;front < back;front++,back--){ c=*front;*front=*back;*back=c; } return str; }
Excelente dato amigo muchas gracias...
Solo mencionar un pequeño aporte, si haces el prework antes de este curso o cualquier a de C, debes considerar que al abrir VSCode utilizas Ubuntu como shell y ello te dará errores cuando compiles con librerias math.h y string.h, te sugiero abrir VSCode desde el menu inicio (windows) para que funcione la extensión Compile Run y las librerias que habla el profesor Ricardo
gracias por la recomendación
Muchas gracias por la recomendación.
Algo a tomar en cuenta, es que gets es peligroso y no se deberia de usar: https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used
De hecho si tratas de compilar usando la función gets() en algunos IDEs, particularmente en Codeblocks, te arroja un error que no te dejará compilar:
Otras funciones de la libreria String
man string
STRING(3) Linux Programmer's Manual STRING(3) NAME stpcpy, strcat, strchr, strcmp, strcoll, strcpy, strcspn, strdup, strfry, strlen, strncat, strncmp, strncpy, strpbrk, strrchr, strsep, strspn, strstr, strtok, strxfrm, - string operations SYNOPSIS #include <string.h> char *stpcpy(char *dest, const char *src); Copy a string from src to dest, returning a pointer to the end of the resulting string at dest. char *strcat(char *dest, const char *src); Append the string src to the string dest, returning a pointer dest. char *strchr(const char *s, int c); Return a pointer to the first occurrence of the character c in the string s. int strcmp(const char *s1, const char *s2); Compare the strings s1 with s2. int strcoll(const char *s1, const char *s2); Compare the strings s1 with s2 using the current locale. char *strcpy(char *dest, const char *src); Copy the string src to dest, returning a pointer to the start of dest. size_t strcspn(const char *s, const char *reject); Calculate the length of the initial segment of the string s which does not contain any of bytes in the string reject, char *strdup(const char *s); Return a duplicate of the string s in memory allocated using malloc(3). char *strfry(char *string); Randomly swap the characters in string. size_t strlen(const char *s); Return the length of the string s. char *strncat(char *dest, const char *src, size_t n); Append at most n characters from the string src to the string dest, returning a pointer to dest. int strncmp(const char *s1, const char *s2, size_t n); Compare at most n bytes of the strings s1 and s2. char *strncpy(char *dest, const char *src, size_t n); Copy at most n bytes from string src to dest, returning a pointer to the start of dest. char *strpbrk(const char *s, const char *accept); Return a pointer to the first occurrence in the string s of one of the bytes in the string accept. char *strrchr(const char *s, int c); Return a pointer to the last occurrence of the character c in the string s. char *strsep(char **stringp, const char *delim); Extract the initial token in stringp that is delimited by one of the bytes in delim. size_t strspn(const char *s, const char *accept); Calculate the length of the starting segment in the string s that consists entirely of bytes in accept. char *strstr(const char *haystack, const char *needle); Find the first occurrence of the substring needle in the string haystack, returning a pointer to the found substring. char *strtok(char *s, const char *delim); Extract tokens from the string s that are delimited by one of the bytes in delim. size_t strxfrm(char *dest, const char *src, size_t n); Transforms src to the current locale and copies the first n characters to dest. DESCRIPTION The string functions perform operations on null-terminated strings. See the individual man pages for descriptions of each function. SEE ALSO index(3), rindex(3), stpcpy(3), strcasecmp(3), strcat(3), strchr(3), strcmp(3), strcoll(3), strcpy(3), strcspn(3), strdup(3), strfry(3), strlen(3), strncasecmp(3), strncat(3), strncmp(3), strncpy(3), strpbrk(3), strrchr(3), strsep(3), strspn(3), strstr(3), strtok(3), strxfrm(3) COLOPHON This page is part of release 4.15 of the Linux man-pages project. A description of the project, information about reporting bugs, and the latest version of this page, can be found at https://www.kernel.org/doc/man-pages/. 2014-01-04 STRING(3)
Para los que tengan problema con GETS, FGETS, etc, Este video lo explica todo: https://youtu.be/Lksi1HEMZgY
La funcion strrev(string) me marca muchos errores, ¿ Hay alguna funcion similar para compiar con gcc en linux ?
strrev no está presente en el compilador GCC que regularmente se instala en linux. Puedes usar la siguiente implementación:
#include <string.h> char *strrev(char *str) { if (!str || ! *str) return str; int i = strlen(str) - 1, j = 0; char ch; while (i > j) { ch = str[i]; str[i] = str[j]; str[j] = ch; i--; j++; } return str; }
Buensimo el algoritmo, doy mi aporte explicandolo:
Con el if, verificamos si hay una string.
Con int i = strlen(str) - 1, lo que hacemos es posicionar a la variable I en el final de la string, supongamos que nuestra string mide 8 posiciones, entonces, nosotros posicionamos a I en la 8octva, si mide 15, la posicionamos en la 15 posicion. Esto hara que I tome los caracteres mas grandes, y J los mas pequenios y al pasar por el bucle, iremos reemplazando los caracteres de I por J. Asi hasta que el bucle se rompa. Es decir, hasta que I sea menor que J.
Alguien sabe como reemplazar el "gets"? Porque por lo que encontré en internet es una función que ya no existe, y "fgets" no me funciona.
fgets sirve para leer texto de un otro archivo, puedes coger la entrada del usuario escribiendo stdin. Otra opción es getline.
#include <stdio.h> #include <string.h> char * string1; size_t size; char string2[60]; char enter; int main() { printf("Type a sentence: \n"); getline(&string1, &size, stdin); string1[strlen(string1)-1] = '\0'; printf("Type another sentence: \n"); fgets(string2, size, stdin); string2[strlen(string2)-1] = '\0'; printf("%s \n", string1); printf("%s \n", string2); return 0; }
La variable size del tipo size_t es para que no haya problemas con que el usuario ingrese un texto más largo del definido.
Comprueba para que sirve la línea string1[strlen(string1)-1] = '\0' comentándola y viendo la diferencia de cuando no está 😀
Si lo estas utilizando en linux el compilador te arroja error, sin embargo, el archivo en binario si se hace y si puedes correrlo sin problema
gets no debería usarse, NUNCA. Pueden usar fgets, que es completamente seguro.
Por otro lado, también hay 2 bibliotecas importantes que son útiles para el manejo de cadenas de texto: <wchar.h> <stddef.h>
Si se han dado cuenta, al imprimir carácteres fuera del rango ASCII estándar (como la ñ y vocales acentuadas), con %s y%ls se ve el texto sin problema (asumiendo que el escaneo de entrada fue con eso mismo o con fgets) pero si intentan imprimir el carácter individualmente con %c, les arrojará mojibake. Para imprimir carácteres especiales hacen uso de cualquiera de estas 2 bibliotecas, configuran el locale y ya podrán mostrar estos carácteres uno por uno correctamente con %lc Y para finalizar, si la consola se atasca, pueden usar freopen() para cambiar el flujo del stream ya que cada vez que se imprime o se lee texto wide con wprintf/wscanf este flujo es modificado y no vuelve automáticamente “a la normalidad”. A menos que usen un solo tipo de texto (char o widechar) a lo largo de todo el código, esto será necesario para desatascar la lectura y escritura de datos si mezclan chars con widechars. Por ejemplo:
#include <stdio.h> #include <wchar.h> #include <locale.h> #include <string.h> int main() { setlocale(LC_ALL, ""); char mitexto[64]; wchar_t mitexto_w[128]; printf("Este es una entrada de texto estándar:\n> "); scanf("%s", &mitexto); freopen(NULL, "r", stdin); freopen(NULL, "w", stdout); wprintf(L"Este es una entrada de texto widestring:\n> "); wscanf(L"%ls", &mitexto_w); freopen(NULL, "w", stdout); putchar('S'); printf("\nEste es una salida de texto estándar: '%s'\n", mitexto); for(int i = 0; i <= strlen(mitexto); i++) printf("%i-%c\n", mitexto[i], mitexto[i]); freopen(NULL, "w", stdout); putwchar('W'); wprintf(L"\nEste es una salida de texto widestring: '%ls'\n", mitexto_w); for(int i = 0; i <= wcslen(mitexto_w); i++) wprintf(L"%i-%lc\n", mitexto_w[i], mitexto_w[i]); return 0; }
Nota: La L es un prefijo necesario para indicar que se trata de un texto longstring o widechar, este prefijo no se usa con fgetws o scanf, pero con wscanf y wprintf sí.
¿Alguien sabe cómo ponerle un espacio entre ambos strings comparados con strcat para que se vea mejor?
strcat(string1, string2); //Espacio entre el string1 y string2 en el resultado printf.
Hola lo puedes hacer de la siguiente forma:
Anexo el código
#include <stdio.h> #include <string.h> char string1[60]; char string2[60]; char space[1] = " "; int main() { printf("Escribe una frase: \n"); gets(string1); printf("Escribe otra frase para comparar: \n"); gets(string2); if (strcmp(string1, string2) == 0) { printf("ingresaste dos strings idénticos\n"); } else { strcat(string1, space); strcat(string1, string2); printf("Ingresaste dos cosas distintas, si las unimos, el resultado es: %s\n", string1); } return 0; }```
En AWS Cloud9 no puedo usar gets() ahí debo usar fgets()
ATENCION con gets.
gets puede porvocar buffer overflow osea puede sobrescribir un dato encima de otro. El compilador no da error pero es peligroso cuando lo de o cuando se trabaja con mayores datos o proyectos.
De notar que el profesor dio 6 caracteres como espacio fijo en nuestros array, 5 para la stringa y un 0 para el final, el cero siempre ocupara el ultimo lugar de una array en fomato char, por eso hay que saber el rango de espacio de caracteres que se quiera ingresar. Pero escribio mas de 5 caracteres en la consola y no nos dio error aunque si deberia darlo ps nuestro espacio era solo de 5 caracteres mas el 0. Por eso el gets() es peligroso y obsoleto, porque no nos da la certeza si estamos esscribiendo un buen codigo.
Hay otro metodo mas seguron y es fgets() o usar
📝Strings en C
📌 Concepto clave
🔤 Un string en C es un array de caracteres (char) terminado en \0.
📚 Se manipula con la biblioteca string.h.
🗂️ Almacenamiento de strings
char string1[60]; // Array de 60 caracteres
gets(string1); // ⚠️ Inseguro
✅ Alternativa más segura:
fgets(string1, 60, stdin); // Limita la longitud
🔄 strrev → Invertir un string
strrev(string1);
printf("Al revés: %s\n", string1);
🔹 Cambia el orden de los caracteres.
🔹 Útil para verificar palíndromos.
⚖️ strcmp → Comparar strings
if (strcmp(string1, string2) == 0) {
printf("Son iguales");
} else {
printf("Son diferentes");
}
📍 Resultado:
➕ strcat → Concatenar strings
strcat(string1, string2);
printf("Concatenados: %s\n", string1);
🔹 Une el contenido de string2 al final de string1.
💡 Consejos rápidos
✨ Cuida los argumentos → asegúrate de pasar correctamente los strings.
✨ Mayúsculas/minúsculas importan en las comparaciones.
✨ Explora más funciones:
que pasa con las lestras ñ ya que la concatenacion o el printf corta el string en la ñ????
hay alguna manera de colocar una palabra y que la reconozca sin importar como la escriba? por ejemplo si la escribe con mayusculas, minusculas o entre mayusculas y minusculas la reconozca?
A alguien más le salió que la función gets es obsoleta..?
Hola, por favor su apoyo y sugerencias. Requiero de un código que tenga como entrada un string y seleccione e imprima las vocales y consonantes en dos lineas diferentes. es decir, si el string de entrada es: felipe debería imprimir:
- vocales: eie consonantes: flp
Les comparto mi actual código el problema es que imprime el texto “vocales” de forma repetitiva al igual que “consonantes”. No se como solicionarlo. De antemano gracias por sus aportes.
#include<stdio.h> #include<string.h> int main(){ char SS[50]; scanf("%s", SS); for(int i =0; i<= strlen(SS); i++){ if(SS[i] == 'a' || SS[i] == 'e' || SS[i] == 'i' || SS[i] =='o' || SS[i] == 'u'){ printf("vocales: %c\n", SS[i]); }} for(int i =0; i< strlen(SS); i++){ if(SS[i] != 'a' && SS[i] != 'e' && SS[i] != 'i' && SS[i] != 'o' && SS[i] != 'u'){ printf("consonantes %c\n", SS[i]); }} }
Hola, yo intentaria usando else despues del primer if, en vez de usar otro for. Algo asi:
for(int i =0; i<= strlen(SS); i++){ if(SS[i] == 'a' || SS[i] == 'e' || SS[i] == 'i' || SS[i] =='o' || SS[i] == 'u'){ printf("vocales: %c\n", SS[i]); } else printf("consonantes %c\n", SS[i]); }
espero te sirva.
Hola, alguien sabe como funciona strcat, me causa duda el hecho de que no le pasaras el apuntador de la variable string 1 y aún así fue capaz de guardar en la misma dirección. :-O
strcat, al igual que las funciones de strxxx y wcsxxx de las librerías <string.h> y <wchar.h>, respectivamente, toman como parámetro valores de tipo string, por lo tanto cuando llamas la función strcat(string1, string2) lo que sucede es que hace una "suma" de strings dándote como resultado la unión de las mismas, el primer parámetro de strcat es el destino donde se guardará el nuevo valor concatenado, y el segundo parámetro es la fuente a concatenar. Es como hacer esta operación: int a, b, resultado; a = 1; b = 2; resultado = a + b; // resultado = 3 strcat hace exactamente lo mismo que la variable resultado, toma 2 valores como argumento, los une en uno solo y sobreescribe el resultado en el primer parámetro, que en este caso es string1, con la diferencia de que en operaciones matemáticas el resultado de cualquier operación solamente se sobreescribe en la variable final y no modifica los parámetros de entrada iniciales.
Hoy en día 2024 la funcion gets esta obsoleta, en su lugar se puede usar la funcion fgets que necesita 3 parametros.
.