Guardar una frase en los elementos de un vector

Iniciado por GominaTilted, 8 Diciembre 2018, 17:39 PM

0 Miembros y 2 Visitantes están viendo este tema.

GominaTilted

Buenas, debo de realizar este ejercicio (lo del título es una supuesta forma correcta pero que no sé implementar). El programa debe de pedir una frase al usuario (hasta ahí todo bien), y luego mostrar las palabras que la componen de forma enumerada (y ahí está el problema xD). Debo de usar la librería <string>, como es lógico, y todas las funciones asociadas. Un banco de pruebas sería el siguiente:

CitarDame frase: Esto es una prueba
1 -> Esto
2 -> es
3 -> una
4 -> prueba

AlbertoBSD

Mejor di que quieres que te hagan la tarea.


El codigo presenta varios problemas, el numero de espacios no puede ser mas de 10, ya que definimos *vector[10], se podria hacer de forma dinamica para aceptar "infinitos" pero eso ya involugra mas codigo.


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

int main() {
char cadena[100];
char *token;
char *vector[10];
int i = 0;
printf("Ingrse una frase: ");
fgets(cadena,100,stdin);
token = strtok(cadena," ");
do {
vector[i] = token;
printf("%i -> %s\n",i+1,vector[i]);
i++;
token = strtok(NULL," ");
}while(token != NULL);
}
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

GominaTilted

Cita de: AlbertoBSD en  8 Diciembre 2018, 17:53 PM
Mejor di que quieres que te hagan la tarea.


El codigo presenta varios problemas, el numero de espacios no puede ser mas de 10, ya que definimos *vector[10], se podria hacer de forma dinamica para aceptar "infinitos" pero eso ya involugra mas codigo.


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

int main() {
char cadena[100];
char *token;
char *vector[10];
int i = 0;
printf("Ingrse una frase: ");
fgets(cadena,100,stdin);
token = strtok(cadena," ");
do {
vector[i] = token;
printf("%i -> %s\n",i+1,vector[i]);
i++;
token = strtok(NULL," ");
}while(token != NULL);
}

Realmente no quería un código (aunque lo pueda parecer por decir lo de <string>), solo una clave para poder sacarlo, pero gracias de todas formas. Ah, por cierto, no sé lo que son los tokens :/

AlbertoBSD

Token:

Citara thing serving as a visible or tangible representation of a fact, quality, feeling, etc.


Dame frase: Token1 Token2 Token3 Token4
1 -> Token1
2 -> Token2
3 -> Token3
4 -> Token4
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

MAFUS

Si el enunciado es mostrar una frase palabra a palabra lo puedes simplificar tanto como:
Recorre la frase de principio a fin. Si encuentras un espacio escribe un avance de línea, en caso contrario escribe el carácter que has encontrado.


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

int main() {
char cadena[100];
printf("Ingrse una frase: ");
scanf("%100s", cadena);

for(int i=0; i<strlen(cadena); ++i)
        putchar(isblank(cadena[i])? '\n' : cadena[i]);
}

GominaTilted

Bueno, he conseguido hacerme mi codigo, y ha quedado así:


#include <iostream>
#include <string>
using namespace std;

void Cabecera (void);
void SepararPalabras (void);

int main (void)
{
Cabecera();
SepararPalabras();
return 0;
}
void Cabecera (void)
{
cout << "Este programa pide una frase y devuelve enumeradas sus palabras" << endl << endl;
return;
}
void SepararPalabras (void)

string frase;
int i, x = 1, n;
cout << "Dame una frase: ";
getline (cin, frase);
for (i = 0; i < frase.length (); i++)
{
if (isalpha (frase[i]))
{
cout << x << "-> ";
while (isalpha (frase[i]))
{
frase[i];
cout << frase[i];
i++;
}
cout << endl;
x++;
}
}
return;
}


Como véis lleva un contador de las palabras (no lo pedía el enunciado, pero como el ejemplo lo incluía pues lo he puesto). Se me olvidó mencionar que me obligan a gastar estan librerías. Ahora le estoy dando vueltas para que omita palabras repetidas, si se os ocurre algo (y no necesito un código directamente), me sería muy útil.

MAFUS

Para eso no debes usar la técnica de letra a letra sino que deberás separar las palabras con un array de strings y a cada palabra que consigas mirar si ya existe en el array.

K-YreX

#7
GominaTilted, respecto a tu código:
- Las funciones que no reciben parámetros, no hace falta que pongas <void>. Eso creo que es más de C, en C++ se suele dejar vacío.
Código (cpp) [Seleccionar]

void Cabecera()

- Y la función <Cabecera()> no tiene mucho sentido, sólo para hacer un <cout>. Si fuese un conjunto de instrucciones más grande o fuese un titulo muy trabajado... Pero para hacer un <cout> lo puedes hacerlo directamente en el <main>.
- Además si no devuelven ningún valor puedes omitir el <return> del final. No es muy habitual ver un <return> en una función de tipo <void>.

Respecto a tu problema de omitir palabras que estén repetidas, la idea siempre es la misma, tener un contenedor de palabras (seguramente usarás arrays pero también puedes usar un contenedor de la STL), coger una palabra, recorrer el contenedor y si no existe ya, la metes en el contenedor.

He estado probando un código que hice hace poco para separar palabras y he intentado adaptarlo para este problema. Sin embargo, sólo me coge la primera palabra. He mirado el código original del que he sacado la estructura de la función y en el original funciona perfecto pero no consigo dar con el problema. El código que he intentado adaptar es este:
Código (cpp) [Seleccionar]

#include <iostream>
#include <string>

using namespace std;

const int MAX_PALABRAS = 20;

size_t SepararPorPalabras(string, string*);

int main(){
string frase;
string palabras[MAX_PALABRAS];
size_t numPalabras;

cout << "Ingresa una frase: ";
getline(cin, frase);

numPalabras = SepararPorPalabras(frase, palabras);

cout << "La frase tiene " << numPalabras << " palabras: " << endl;
for(size_t i = 0; i < numPalabras; i++)
cout << "Palabra " << i+1 << ": " << palabras[i] << endl;

}

size_t SepararPorPalabras(string frase, string *palabras){
size_t numPalabras = 0, letrasPorPalabra;
string palabra;

while((letrasPorPalabra = frase.find(' ')) != string::npos && numPalabras < MAX_PALABRAS){
palabra = frase.substr(0, letrasPorPalabra);
frase.erase(0, letrasPorPalabra+1);
palabras[numPalabras++] = palabra;
}
if(numPalabras < MAX_PALABRAS){
palabra = frase.substr(0, letrasPorPalabra);
palabras[numPalabras++] = palabra;
}
return numPalabras;
}


La salida del programa es la siguiente:

Ingresa una frase: frase de prueba
La frase tiene 1 palabras:
Palabra 1: frase


Si alguien puede echarme una mano para encontrar el error.  :-X :-X
Código (cpp) [Seleccionar]

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

GominaTilted

YreX-DwX, gracias por el aporte. Si consigo sacar algo te aviso xD. Luego tengo que corregir el ejercicio, osea que supongo que obtendré una solución óptima.

CalgaryCorpus

Esto
Código (cpp) [Seleccionar]
cin >> frase;
solo lee la primera palabra. No lee la frase completa.
Aqui mi perfil en LinkedIn, invitame un cafe aqui