Hola, estoy haciendo un programa para contar el numero de palabras que tenga una frase, el problema es que por supuesto siempre el numero de palabras varia, por lo que segun pienso yo, hay que usar memoria dinamica
int main(int argc, char *argv[])
{
char Lectura[200], *PTok, **Palabras=NULL;
int i=0, j=0, ContPal=1;
cin.getline(Lectura, sizeof(Lectura));
PTok=strtok(Lectura," ");
while ( PTok!= NULL )
{
AgrEspacio(Palabras, ContPal);//AgrEspacio Agrega Una Fila De Mas A Palabras
strcpy( Palabras[i], PTok );
PTok=strtok(NULL," ");
i+=1;
ContPal+=1;
}
for ( j=0; j<i; j++ )
cout<<Palabras[j]<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}
El problema como tal es esa funcion para agregar una fila a la matriz, ya que si compila, pero estoy violando el acceso a la memoria en una parte del codigo de esa funcion
void AgrEspacio ( char **Palabras, int NumPal)
{
char **TemFilas=new char*[NumPal];
for ( int i=0; i<NumPal; i++ )
{
TemFilas[i]=new char[200];
TemFilas[i]=Palabras[i];
}
Palabras=TemFilas;
}
La verdad este tema de memoria dinamica se me hace un poco dificil de entender, ya que no se bien cuando es correcto usarla, por ejemplo en este ejercicio podria haber creado una matriz estatica como char Palabras[100][200];
en vez de pensar en memoria dinamica, pero la ventaja es que con esta voy agregando filas a mi matriz cuando lo voy necesitando en vez de declarar una estatica y ocupar memoria que tal vez no usare
Gracias por su tiempo.
no es mas facil un
(usando string.h)
char lectura[200];
int i = 0;
int j = 0;
cin >> lectura;
for(i=0;i<strlen(lectura);i++){
if(lectura[i]==' ')
j++;
}
cout >> "hay " >> j >> " palabras";
creo que necesita un par de retoques, pero deberia funcionar
Esque la salida del programa deve de ser asi:
Entrada: "Anita Lava La Tina"
Salida: Anita --> 1 vez
Lava --> 1 vez
La --> 1 Vez
Tina --> 1 Vez
void AgrEspacio ( char **Palabras, int NumPal)
{
char **TemFilas=new char*[NumPal];
for ( int i=0; i<NumPal; i++ )
{
TemFilas[i]=new char[200];
TemFilas[i]=Palabras[i];
}
Palabras=TemFilas;
}
1º Palabras debe pasarse por referencia (&).
2º La igualación TermFilas = Palabras no tiene ningún sentido. Te estas cargando lo que acababas de reservar con new.
Saludos.
Lo que queria hacer al igualar TemFilas[i]=Palabras[i];
era copiar el contenido ya que TemFilas[i]
tiene un espacio de mas y esa es la que quiero usar[/size]
No, no haces eso. La función te irá perfectamente así:
void AgrEspacio ( char **&Palabras, int NumPal)
{
char **TemFilas=new char*[NumPal];
for ( int i=0; i<NumPal; i++ )
{
TemFilas[i]=new char[200];
}
Palabras=TemFilas;
}
Aunque yo eliminaria la variable auxiliar:
void AgrEspacio ( char **&Palabras, int NumPal)
{
Palabras =new char*[NumPal];
for ( int i=0; i<NumPal; i++ )
{
TemFilas[i]=new char[200];
}
}
No es necesario usar memoria dinámica... al menos no es necesario que tú te encargues de ello.
Sería más sencillo usando un vector:
int main(int argc, char *argv[])
{
char Lectura[200], *PTok;
vector< string > Palabras;
int i=0, j=0, ContPal=1;
cin.getline( Lectura, sizeof( Lectura ) );
PTok = strtok(Lectura," " );
while ( PTok != NULL )
{
Palabras.push_back( PTok );
PTok = strtok( NULL, " " );
}
for ( int i=0; i < Palabras.size( ); i++ )
cout<<Palabras[ i ] << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Está muy bien que aprendas a usar memoria dinámica es un recurso muy potente... pero si la usas acuérdate de liberarla después.
Cita de: Omar_2013 en 11 Marzo 2014, 22:38 PM
Lo que queria hacer al igualar TemFilas[i]=Palabras[i];
era copiar el contenido ya que TemFilas[i]
tiene un espacio de mas y esa es la que quiero usar[/size]
Si tu haces TemFilas
= Palabras... teniendo en cuenta que ambas variables son punteros... estás haciendo que el puntero TemFilas apunte a Palabras, en otras palabras:
* situación inicial:
TemFilas = 0xF093 <-- Basura
Palabras = 0x1234 <-- Dirección apuntada por el puntero
* Con TemFilas = new char[200]; tenemos
TemFilas = 0x8000 <-- Posición de inicio del array recién reservado
Palabras = 0x1234 <-- Dirección apuntada por el puntero
* Con TemFilas=Palabras
TemFilas = 0x1234 <-- Perdiste toda referencia a la posicion 8000 que es donde está el array recién creado
Palabras = 0x1234 <-- Dirección apuntada por el puntero
¿Qué quiere decir esto? Lo siguiente. Una vez haces TemFilas = Palabras sucede lo siguiente:
strcpy( Palabras[i], "prueba" );
cout << Palabras[i] << "-" << TemFilas[i] << endl; // Imprime: prueba-prueba
TemFilas[i][2] = '#';
cout << Palabras[i] << "-" << TemFilas[i] << endl; // Imprime: pr#eba-pr#eba
Esto es así porque los dos punteros apuntan a la misma cadena y cualquier cambio en la cadena se ve reflejado en los dos punteros.
Como ya te comento eferion deberías utilizar la biblioteca estándar de C++. Puedes utilizar las clases vector y string para que ellas se encarguen del manejo de memoria y la clase istringstream para obtener las palabras de la linea. Por ejemplo:
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <string>
using std::string;
using std::getline;
#include <vector>
using std::vector;
#include <sstream>
using std::istringstream;
int main()
{
cout << "Introduce la linea: ";
string linea;
getline(cin, linea);
istringstream is(linea);
vector<string> palabra;
string aux;
while (is >> aux)
palabra.push_back(aux);
// En C++11 se puede utilizar "auto" para abreviar la declaracion
for (vector<string>::size_type i = 0; i != palabra.size(); ++i)
cout << i << ": " << palabra[i] << endl;
return 0;
}
Un saludo