cadenas y uso de MAYUSCULA

Iniciado por JoshDur, 25 Noviembre 2019, 01:22 AM

0 Miembros y 1 Visitante están viendo este tema.

JoshDur

estoy comenzando con la carrera y estoy bloqueado con esta tarea en particular.

Mi tarea es sobre hacer un programa que convierte en MAYÚSCULA la ultima palabra de una frase con C

K-YreX

No sé si tienes alguna restricción en cuanto a que tengas que implementarlo todo sin utilizar funciones que ya existen...
Si no es tu caso y puedes usar funciones tienes:
  • strrchr() de la librería <string.h> que te devuelve un puntero a la última coincidencia de un caracter dado.
  • toupper() de la librería <ctype.h> que convierte un caracter en mayúscula.

    Si no puedes usar dichas funciones y tienes que implementarlo tú, te recomendaría hacer una función que dado un <char[]>, te devuelva la posición (índice) en el que empieza la última palabra; y luego con un bucle vas convirtiendo cada letra en mayúscula.
    En ASCII una letra minúscula vale 28 más que en mayúscula si no me equivoco por lo que si haces:

    char minuscula = 'a';
    char mayuscula = minuscula - 28; // esto deberia guardar 'A'

    // Sino siempre puedes hacer:
    char minuscula = 's';
    char mayuscula = minuscula - ('a' - 'A'); // esto deberia dar 'S'


    Es posible que si acabas de empezar, esto que te acabo de soltar te suene a chino y no entiendas nada. Si tienes alguna duda o no consigues avanzar en tu tarea, puedes poner el código en un mensaje entre etiquetas de Código GeSHi para que podamos ayudarte mejor.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

JoshDur

no tengo restricción siempre y cuando sea en ".C", mi verdadera duda es poder "tomar" la ultima palabra que el usuario escriba y escribir nuevamente la frase con la ultima palabra en mayúscula.

K-YreX

Las palabras en C se toman en un array de char, o lo que es lo mismo, una cadena de caracteres, un vector. Cada posición de la cadena contiene un caracter, pongamos el típico ejemplo: "hola mundo". Al guardar esto en C quedaría así:

char frase[] = "hola mundo";
// Internamente queda guardado como:
// frase = |'h'|'o'|'l'|'a'|' '|'m'|'u'|'n'|'d'|'o'|'\0'|

El último es un carácter especial que utiliza C para saber donde acaba la cadena. Se pone implícitamente.
Entonces si haces:

printf("%s", frase); // muestra: "hola mundo" sin las comillas
//pero si haces:
printf("%s", frase+5); // muestra: "mundo" sin las comillas porque empieza a mostrar 5 posiciones mas a la derecha


Como puedes usar las funciones que te dije anteriormente, sólo tienes que crear un puntero que como su nombre indica apunta y hacer que apunte al comienzo de la última palabra:

char frase[] = "hola mundo";
char *puntero = strrchr(frase, ' '); // devuelve un puntero apuntando al ultimo espacio de la frase
++puntero; // incrementas el puntero para que apunte a la primera letra de la palabra
while(*puntero != '\0'){ // mientras no acabe la cadena
    *puntero = toupper(*puntero); // modificas el valor de cada celda por su mayuscula correspondiente
    ++puntero; // sigues avanzando
}


Al final resulta que prácticamente te lo he dado hecho pero me parecía que sino te ibas a liar con lo de punteros, el asterisco, los incrementos, las funciones esas, etc.
El puntero es como una variable que en vez de guardar un valor como tal, guarda una posición de memoria. Para acceder al contenido de dicha posición de memoria se utiliza el asterisco (lo que se conoce como desreferenciar el puntero).

char letra = 'a';
char *puntero = &letra; // el asterisco determina que se trata de un puntero y el & devuelve la direccion de memoria de la variable (letra en este caso)
printf("%d", puntero); // posicion de memoria de la variable letra
printf("%c", *puntero); // contenido de la variable a la que apunta el puntero (letra)


Estoy intentando aclararlo pero cuanto más escriba creo que más complejo lo voy a dejar así que si hay cosas que de momento no entiendes, no te preocupes. Ya irás avanzando en el curso y al final verás como esto es una tontería.

PD: Para pedir valores se suele usar <scanf()> pero si se trata de una cadena, lo recomendable y seguro es hacerlo con <fgets()>:

char cadena[50]; // cadena de longitud maxima 50
printf("Introduce una cadena: ");
fgets(cadena, 50, stdin);

Lo malo de esta función es que también guarda el ENTER que pulsas al final por lo que si introduces "hola", en la cadena se guardaría como:
cadena = |'h'|'o'|'l'|'a'|'\n'|'\0'|
La '\n' determina un salto de línea. Para eliminar eso es muy sencillo ahora que ya te he mostrado como funciona <strrchr()>:

// supongamos que el usuario introduce "hola mundo". La cadena quedaria:
char cadena[] = "hola mundo\n"; // recordemos que siempre acaba en '\0'
char *final = strrchr(cadena, '\0'); // busca el '\0' que siempre va a estar el ultimo
*(--final) = '\0'; // nos vamos una posicion para atras y ponemos el '\0' ahi para eliminar el '\n'

Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

JoshDur

eres un héroe sin capa, gracias por la explicación que fue mejor que el que me da el profesor. nuevamente gracias

CalgaryCorpus

Buscar el ultimo espacio en blanco podria fallar si la frase tiene solo 1 palabra, sin espacio alguno.

Tal vez resulte mejor poner un puntero al final y devolverse hasta llegar o al inicio de la palabra o bien a un espacio en blanco.
Aqui mi perfil en LinkedIn, invitame un cafe aqui

K-YreX

Cita de: CalgaryCorpus en 26 Noviembre 2019, 15:11 PM
Buscar el ultimo espacio en blanco podria fallar si la frase tiene solo 1 palabra, sin espacio alguno.

Tal vez resulte mejor poner un puntero al final y devolverse hasta llegar o al inicio de la palabra o bien a un espacio en blanco.
Cierto, se podría arreglar así:

char *puntero = strrchr(frase, ' ');
if(puntero == NULL)
    puntero = frase;

La otra manera que comentabas también es posible.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;