Programa para distinguir palindromos:

Iniciado por Error 404:, 27 Junio 2014, 12:33 PM

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

Error 404:

Hola a todos
Os cuento, hoy me he puesto a hacer un programa bastante básico, que consiste en introducir una palabra o una frase y te devuelve si es un palíndromo o no.
Puesto que aún tengo un nivel muy muy básico (por no decir malo) al principio he aclarado que nunca se utilicen espacios, ni mayúsculas, ni acentos, y en fin, cualquier cosa que dificulte mucho más la programación.
Bueno os dejo el programa y la localización y el fallo que me pone, supongo que es importante decir que utilizo DEV-C++.
Espero que me d¡gáis una pista o algo de como solucionarlo, gracias.

#include <iostream>
#include <cstring>
using namespace std;
int n;
bool palindromo;
int j;
int main(){
    int i;
    char cadena;
   
    cout << "Introduzca una palabra o cadena de ellas sin utilizar espacios y/o" << endl;
    cout << " mayusculas, minusculas, acentos, etc. El programa le dira si la" << endl;
    cout << " cadena introducida es un palindromo."<< endl;
   
    cin >> cadena;
    cin.get();
    if (palindromo) cout<< "Es un palindromo.";
    else cout<< " No es un palindromo.";

cin.get();
return 0;
}

bool palindromo
{        //AQUI MARCA EL FALLO Y PONE: INVALID FUNCTION DECLARATION
     int j = sizeof(cadena)/sizeof(cadena[1]);
     int k = 1;
     do{
         if(strcmp(cadena[k],cadena[j])==0) k++ j-- n=1;
         else n=0;
         } while( k != j+1 && n!=0);
         if (n==1) return true; else return false;
}


Gracias por adelantado.
Si se puede imaginar, se puede programar.

eferion

Respeta la nomenclatura de las funciones

Todas las funciones en C y C++ tienen la siguiente forma:

TIPO_RETORNO nombreFuncion( [ARGUMENTOS] ){ }

En tu caso, palindromo no respeta esta nomenclatura ya que, por ejemplo, no tiene los paréntesis (nota que "argumentos" está entre corchetes... esto es porque son opcionales... sin embargo el resto es obligatorio).

No uses variables globales

Es muy cómodo declarar una variable global al inicio del programa y después olvidarse de pasar argumentos a las funciones. El pero es que esta forma de trabajar provoca más problemas que beneficios.

Declarar una variable dentro de una función es prácticamente gratis y usar los argumentos te permite aislar el código de forma más eficaz. Además el código queda mucho más legible.

Para gestionar cadenas, usa char* o, mejor aún, la clase string

char únicamente permite almacenar un carácter. Es decir, para leer una cadena necesitas un array de caracteres. Los arrays de caracteres se declaran tal que "char* cadena". Eso sí has de tener en cuenta que ahora cadena es un puntero y hay que tener cuidado a la hora de utilizar punteros.

Por ejemplo, para copiar una cadena de caracteres en otra no puedes hacer "cadena1 = cadena2" como queda claro con el siguiente ejemplo:

Código (cpp) [Seleccionar]

char cadena1[10] = "Hola";
char *cadena2;

cadena2 = cadena1;

cadena2[ 0 ] = 'S';

// Imprime por pantalla: Sola
std::cout << cadena1 << std::endl;


Lo que hace la asignación es que el puntero "cadena2" apunta al mismo sitio que "cadena1", por lo que cualquier cambio que se haga en una de las variables afecta directamente a la otra. La forma correcta de copiar cadenas de caracteres es (una de ellas):

Código (cpp) [Seleccionar]

char cadena1[10] = "Hola";
char cadena2[10];

strcpy( cadena2, cadena1 );

cadena2[ 0 ] = 'S';

// Imprime por pantalla: Hola
std::cout << cadena1 << std::endl;


Nota para los del foro: Se que hay formas más seguras de copiar las cadenas de caracteres... esto es un ejemplo ;)

La opción b es hacer uso de una clase diseñada específicamente para gestionar cadenas de caracteres. Hablo de la clase string. string se encarga de hacer todas las operaciones engorrosas de los arrays de caracteres de forma transparente para el programador:

Código (cpp) [Seleccionar]

std::string cadena1 = "Hola";
std::string cadena2;

cadena2 = cadena1;

cadena2[ 0 ] = 'S';

// Imprime por pantalla: Hola
std::cout << cadena1 << std::endl;


Además, string dispone de otras tantas "cosas buenas":

Código (cpp) [Seleccionar]

std::string cadena = "ABCDEF";
std::string cadena2 = cadena + "GHI";

std::cout << "Contenido:" << cadena << std::endl;
std::cout << "Longitud: " << cadena.size( ) << std::endl;
std::cout << "Probando la concatenacion: " << cadena2 << std::endl;
// ...


Aprende a leer los mensajes de error de compilación

Al principio te costará, pero es un paso necesario con el que tienes que pegarte. El compilador te va a dar mucha información, pero has de saber interpretarla correctamente. No tengas miedo a pegarte con ello.

Aprende a usar los depuradores de código

Después de entender los mensajes de compilación, el siguiente paso es meterse de lleno en la depuración de código. Mano de santo para corregir errores a la hora de diseñar la algoritmia de la aplicación.

leosansan

Además de lo ya mencionado por eferion:

* Si declaras n y j como variables globales no tiene sentido que las vuellvas a declarar en la función bool. Mejor no las declaras como globales y sí en bool ya que sólo las usas en ésta.

* La función strcmp"" está pensada para comparar cadenas. En el caso de caracteres se pueden comparar directamente:

Código (cpp) [Seleccionar]
if( cadena[k] != cadena[j-1] )

* Tienes un error lógico. Si el último caracter de la cadena coincide con el primero n=1 y devuelve true, cuando a lo mejor en otros no son iguales.

* En realidad basta recorrer la mitad del array o cadena para saber si es o no palindromo.

* Los índices de los arrays empiezan en cero y tú los empiezas desde 1 (k=1), con lo que se quedara sin comparar el primer caracter.

Con las observaciones de eferion y las que te expongo, una posible solución sería:

Código (cpp) [Seleccionar]
#include <iostream>
#include <cstring>

using namespace std;

bool palindromo ( char cadena[100] );

int main(){
  char cadena[100];
  cout << "Introduzca una palabra o cadena de ellas sin utilizar espacios y/o" << endl;
  cout << " mayusculas, minusculas, acentos, etc. El programa le dira si la" << endl;
  cout << " cadena introducida es un palindromo."<< endl;
  cin >> cadena;
  cin.get();
  if ( palindromo ( cadena ) )
    cout<< "Es un palindromo.";
  else
    cout<< " No es un palindromo.";
  cin.get();
  return 0;
}

bool palindromo ( char cadena[100] ){
  int k = 0, j = tam;
  for ( k = 0; k < tam/2; k++, j-- )
    if( cadena[k] != cadena[j-1] )
      return false;
  return true;
}


¡¡¡¡ Saluditos! ..... !!!!



Error 404:

Antes de todo muchas gracias por la ayuda tan rápida y buena. He realizado algunos cambios pero sigue habiendo algún problema. Aquí va el código:

Código (cpp) [Seleccionar]
#include <iostream>

#include <cstring>

using namespace std;

bool palindromo();

char *cadena;




int main(){


    cout << "Introduzca una palabra o cadena de ellas sin utilizar espacios y/o" << endl;

    cout << " mayusculas, minusculas, acentos, etc. El programa le dira si la" << endl;

    cout << " cadena introducida es un palindromo."<< endl;

   

    cin >> cadena;

    cin.get();

    if (palindromo()) cout<< "Es un palindromo.";

    else cout<< " No es un palindromo.";




cin.get();

return 0;

}

bool palindromo(int n)

{

     int j = sizeof(cadena)/sizeof(cadena[1]);

     int k = 0;

     do{

         if (&cadena[k]!=&cadena[j])( n=0); //AQUI NO ESTOY SEGURO DE QUE
                                       // TENGA QUE USAR LA DIRECCION
         else{       
                     k++;
                     j--;
                     n=1;
                }

       
         } while(k != j-1 || n!=0);

         if (n==1) return false; else return true;

}


El fallo que me pone es: [LINKER ERROR] UNDEFINIED REFERENCE TO ' palíndromo()'
ID RETURNED 1 EXIT STATUS
Si se puede imaginar, se puede programar.

Eternal Idol

Obviando el resto del codigo, ese es un error en el momento de enlazar, la funcion palindromo en su prototipo no recibe parametros y cuando la llamas no le pasas ningun parametro, despues implementas otra que si recibe un parametro de tipo int, en definitiva no hay codigo para la primera y no usas la segunda, arregla el prototipo para que coincida con la implementacion y llama a la funcion con sus parametros correspondientes.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Error 404:

Entonces donde he puesto :
Código (cpp) [Seleccionar]

if (palíndromo())cout<<"es un palíndromo"


Debería poner esto otro:  :huh:

Código (cpp) [Seleccionar]

if (palíndromo(int n))cout<<"es un palíndromo"

Es que si hago ese cambio me sale el error : EXPECTED PRIMARY EXPRESSION BEFORE "int"
Si se puede imaginar, se puede programar.

Eternal Idol

No ... como vas a poner eso ... no se puede programar haciendo copy/paste.

Conseguite un buen libro o al menos un tutorial para empezar desde el princpio.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Error 404:

Estoy con el manual de conclase, ese es un ejercicio que manda  :-\
Si me pudieras explicar lo que me has dicho con un ejemplo te lo agradecería mucho  :-(
Si se puede imaginar, se puede programar.

Eternal Idol

No lo conozco ... por lo menos aca muestra como llamar a una funcion (me resulta increible que en el capitulo 3 no muestren como hacerlo):
http://c.conclase.net/curso/?cap=015#inicio

¿Por donde vas?
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Error 404:

#9
Vale, he conseguido que me compile, pero cuando lo uso me sale que tiene problemas, el típico cuadro de enviar o no informe de errores. Así lo deje:
Código (cpp) [Seleccionar]

#include <iostream>
#include <cstring>
using namespace std;
bool palindromo();
char *cadena;
int main(){

// Voy a obviar la introduccion
   cin >> cadena;
   cin.get();
   if (palindromo(cadena)) cout<< "Es un palindromo.";
   else cout<< " No es un palindromo.";
cin.get();
return 0;
}
bool palindromo(char *cadena)
{
         int n;    
         int j = sizeof(cadena)/sizeof(cadena[1]);
         int k = 0;
         do{
              if (&cadena[k]!=&cadena[j])( n=0);                                      
              else{        
                     k++;
                     j--;
                     n=1;
                    }
        } while(k != j-1 || n!=0);
        if (n==1) return true; else return false;


Si se puede imaginar, se puede programar.