/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Programa me produce error pero sige funcionando

 
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
astut



Registrado: 13 Ene 2007
Mensajes: 8

MensajePublicado: 16/10/2007 9:44 am
Título: Programa me produce error pero sige funcionando

Hola, estoy haciendo un programa simple de consola:
Código:
#include <iostream>

//Variables
char usuario[16];

//Funciones (Propotipos)
bool Preguntar(char pregunta[250]);

int main()
{
    //Peticion de nombre de usuario
   printf("Escribe tu nombre de usuario: ");
   scanf("%16s", usuario);
   system("cls");

   //Cuerpo
   printf("Bienvenido %s\n-----------------------------------\n", usuario);
   if (Preguntar("hola"))
        printf("Dijo que si");
    else
        printf("Dijo que no");
   return 0;
}

//Funciones (definicion)
bool Preguntar(char pregunta[250])
{
    char respuesta;
    printf("%s [S/N]", pregunta);
    scanf("%s", &respuesta);
    if (respuesta== 115)
        return true;
    else
        return false;
}

La cosa es que cuando utilizo la función "Preguntar" me genera el popular error de "Enviar informes de errores", le doy a "no enviar" y el programa continua, pero queda feo este mensaje, ¿porque se genera?

Y lo que ocurre esque estoy liado con el tipo "char":
- const char *variable <- puedo meterle de valor al puntero: "Hola" sin ser cont char *variable un array, ¿porque?
- Si hago un puntero que se diriga a un char, puedo cambiar su valor sin utilizar el operador "*" del modo: *variable= "hola", se hace variable= "hola", ¿porque?

Bueno espero que me puedan orientar, gracias


gracias!
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 3650
Ubicación: Mexico

MensajePublicado: 16/10/2007 2:33 pm
Título: Re: Programa me produce error pero sige funcionando

astut escribió:
La cosa es que cuando utilizo la función "Preguntar" me genera el popular error de "Enviar informes de errores", le doy a "no enviar" y el programa continua, pero queda feo este mensaje, ¿porque se genera?

Porque tu programa tiene varios errores empezando por utilizar funciones como printf y scanf sin antes incluir sus prototipos localizados en <cstdio>.

Y en la funcion "Preguntar" la variable "respuesta" es de tipo char y en esta solo puedes almacenar un unico caracter (tu tratas a esa variable como si fuera un array al pasarla a scanf).

astut escribió:
Y lo que ocurre esque estoy liado con el tipo "char":
- const char *variable <- puedo meterle de valor al puntero: "Hola" sin ser cont char *variable un array, ¿porque?

Porque en C y C++ las cadenas literales como "hola" deben almacenarse en algun lugar y este lugar es un array de caracteres de solo lectura. Cuando tu utilizas la cadena literal esta se procesa como una expresion (salvo ciertos casos) y el resultado de esta es la direccion en memoria donde se almacena el array. Esta direccion tiene el tipo "char *" en C y "char const *" en C++.

astut escribió:
- Si hago un puntero que se diriga a un char, puedo cambiar su valor sin utilizar el operador "*" del modo: *variable= "hola", se hace variable= "hola", ¿porque?

Me parece que te estas confundiendo.

Las variables de tipo "char *" no se distinguen en su uso de cualquier otro tipo de variable. Asi como una variable de tipo int le puedes dar distintos valores:
Código:
int numero;

numero = 5;

numero = 7;

/* ... */


Tambien puedes hacer lo mismo con punteros de tipo "char *":
Código:
char const *p;

p = "hola";

p = "adios";

/* ... */

En este caso lo que se almacena en el puntero "p" no es la cadena sino la direccion en memoria donde esta se almacena.

El operador de indireccion te permite (al ser aplicado a punteros) ya no trabajar con la direccion de memoria de "algo" sino con ese algo llamese entero, caracter, etc.

Por ejemplo si tienes un puntero a caracter de esta forma:
Código:
char ch;
char aux;
char *p;

ch = 'x';
p = &ch;

El valor de ch es 'x' mientras que el valor de p es la direccion en memoria donde se almacena la variable ch.

Si en este momento le das otro valor a la variable p, por ejemplo con:
Código:
p = &aux;

El cambio solo afecta a la variable p y esta ahora almacena la direccion en memoria de la variable aux.

Si lo que se desea no es cambiar el valor del puntero sino utilizar este para afectar indirectamente otro objeto (de ahi el nombre) se utiliza el operador de indireccion y entonces ya no trabajas con la direccion de memoria sino con el objeto en esa direccion de memoria. Por ejemplo para cambiar el valor de la variable ch de 'x' a 'y':
Código:
p = &ch;
*p = 'y'; /* equivalente a "ch = 'y'" */


Un saludo
_________________
The capacity to learn is a gift;
The ability to learn is a skill;
The willingness to learn is a choice.
--
Rebec of Ginaz
Volver arriba
astut



Registrado: 13 Ene 2007
Mensajes: 8

MensajePublicado: 20/10/2007 12:27 pm
Título:

Gracias por la explicacion, pero he arreglado el programa y sige dandome ese dichoso fallo...:
Código:
#include <iostream>
#include <cstdio>

//Variables
char usuario[16];

//Funciones (Propotipos)
bool Preguntar(const char* pregunta);

int main()
{
    //Peticion de nombre de usuario
   printf("Escribe tu nombre de usuario: ");
   scanf("%16s", usuario);
   system("cls");

   //Cuerpo
   printf("Bienvenido %s\n-----------------------------------\n", usuario);
   if (Preguntar("hola"))
        printf("Dijo que si");
    else
        printf("Dijo que no");
   return 0;
}

//Funciones (definicion)
bool Preguntar(const char* pregunta)
{
    char respuesta;
    printf("%s [S/N]", pregunta);
    scanf("%s", &respuesta);
    if (respuesta== 115)
        return true;
    else
        return false;
}


Espero que me podais ayudar, saludos!
Volver arriba
digies



Registrado: 18 Nov 2005
Mensajes: 240
Ubicación: Cono Sur

MensajePublicado: 20/10/2007 3:01 pm
Título:

Hola

No suelo programar en C++ pero aquí va mi aporte. Compílalo bajo C++ y pruébalo. Tal vez hayan headers demás, pero funciona.

Código:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>

using namespace std;

bool Preguntar(const char* pregunta);

int main()
{
   int ch;
   char usuario[16];
   printf("Escribe tu nombre de usuario: ");
   scanf("%16s", usuario);
   system("cls");

   printf("Bienvenido %s\n-----------------------------------\n", usuario);
   //Eliminar los caracteres restantes de la ínea: */
   while((ch=fgetc(stdin))!=EOF && ch!='\n') // Reemplazo al no estandarizado fflush(stdin);
      ; // Descartar el resto de la línea
   if (Preguntar("hola")==true)
        printf("Dijo que si\n");
   else
        printf("Dijo que no\n");
   system("PAUSE");
   return 0;
}

bool Preguntar(const char* pregunta)
{
    char respuesta;
    printf("%s [S/N]: ", pregunta);
    scanf("%c", &respuesta);
    if (respuesta == '\x73')
        return true;
    else
        return false;
}


Un saludo
Volver arriba
digies



Registrado: 18 Nov 2005
Mensajes: 240
Ubicación: Cono Sur

MensajePublicado: 20/10/2007 3:16 pm
Título:

Una pequeña corrección y una sugerencia:

- Elimina el símbolo "*/" que coloqué dentro de un comentario.

- Esto:
Código:
if (Preguntar("hola")==true)

puede ser reemplazado simplemente por:
Código:
if (Preguntar("hola"))


Un saludo
Volver arriba
astut



Registrado: 13 Ene 2007
Mensajes: 8

MensajePublicado: 20/10/2007 9:42 pm
Título:

Gracias por tu programa, pero, yo lo quiero como yo lo hago, busco la solucion a un error no otro programa con añadiciones, ¿Alguien podria? gracias ^^
Volver arriba
cheroky



Registrado: 22 Sep 2005
Mensajes: 1372
Ubicación: En ecx esperando un call

MensajePublicado: 21/10/2007 5:14 am
Título:

astut escribió:
Gracias por tu programa, pero, yo lo quiero como yo lo hago, busco la solucion a un error no otro programa con añadiciones, ¿Alguien podria? gracias ^^

Creo que rir3760 ya te explico con detalle algunos de los errores, particularmente y el mas importante la llamada a scanf, si no quieres ñadidos en tu progra me parece que esto es imposible principalmente por que scanf es una funcion cruda y de algun modo tienes que gestionar la entra estandar y su buffer asociado.

Además tiene otros errores que en tu caso no son perceptibles pero podrían serlo en otros compiladores, como son la llamada a funciones estándar si usar su espacio de nombres std, la llamada a system sin la inclusión de su header correspondiente cstdlib y como ya te indicaron, también la inclusión del header cstdio.


Si aún así te hace ilusión un cuasi calco de tu código:

Código:
#include <cstdio>
#include <cctype>
#include <cstdlib>
using namespace std;

//Variables
char usuario[16];

//Funciones (Propotipos)
bool Preguntar(char pregunta[250]);

int main()
{
    //Peticion de nombre de usuario
   printf("Escribe tu nombre de usuario: ");
   scanf("%16s%*c", usuario);
   system("cls");

   //Cuerpo
   printf("Bienvenido %s\n-----------------------------------\n", usuario);
   if (Preguntar("hola"))
        printf("Dijo que si");
    else
        printf("Dijo que no");
   return 0;
}

//Funciones (definicion)
bool Preguntar(char pregunta[250])
{
    char respuesta;
    printf("%s [S/N]", pregunta);
    scanf("%c", &respuesta);
    if (tolower(respuesta) == 's') // 's' o 'S'
        return true;
    else
        return false;
}


En mi opinión es más interesante que programes en C o C++ de forma radical, esto pasa por no usar ninguna implementación de C en C++.

S2.
_________________
- Explícito es mejor que implícito.
- Simple es mejor que complejo.
- Complejo es mejor que complicado.
- Plano es mejor que anidado.
- Ralo es mejor que denso.
Volver arriba
astut



Registrado: 13 Ene 2007
Mensajes: 8

MensajePublicado: 21/10/2007 5:33 am
Título:

Bueno ya he hecho todo lo que me habeis dicho:
Código:
#include <cstdio>
#include <cctype>
#include <cstdlib>
using namespace std;

//Variables
char usuario[16];

//Funciones (Propotipos)
bool Preguntar(char pregunta[250]);

int main()
{
    //Peticion de nombre de usuario
   printf("Escribe tu nombre de usuario: ");
   scanf("%16s", usuario);
   system("cls");

   //Cuerpo
   printf("Bienvenido %s\n-----------------------------------\n", usuario);
   if (Preguntar("hola"))
        printf("Dijo que si");
    else
        printf("Dijo que no");
   return 0;
}

//Funciones (definicion)
bool Preguntar(char pregunta[250])
{
    char respuesta;
    printf("%s [S/N]", pregunta);
    scanf("%s", &respuesta);
    if (respuesta== 115)
        return true;
    else
        return false;
}

Pero sige ocurriendome.. ¿todavia hay algo mal?, ¿que?

gracias!
Volver arriba
cheroky



Registrado: 22 Sep 2005
Mensajes: 1372
Ubicación: En ecx esperando un call

MensajePublicado: 21/10/2007 5:41 am
Título:

Creo que has entrado en un bucle infinito del cual yo no sabría sacarte, quizás algún compañero del foro...

S2.
_________________
- Explícito es mejor que implícito.
- Simple es mejor que complejo.
- Complejo es mejor que complicado.
- Plano es mejor que anidado.
- Ralo es mejor que denso.
Volver arriba
daltomi



Registrado: 28 Abr 2007
Mensajes: 114
Ubicación: Argentina

MensajePublicado: 21/10/2007 4:46 pm
Título: Depurando el código

Colapsa con un espacio en blanco.

Teniendo en cuenta que, dentro del segmento Main(..), usuario = "abc defg", ingresado por mi.

Automáticamente, dentro del segmento Preguntar(..),respuesta = "d".
El programa finaliza.

Edito: ok, me veo obligado a ser más específico:
Compilado en VC++ v.6.0
Plataforma Windows ME
El código es el de Cheroky ya que todavía existen errores en el código de astut.

Faltaría notar si es el error que se produce en mi compilación, es el que da el fallo a astut.

Saludos.
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 3650
Ubicación: Mexico

MensajePublicado: 21/10/2007 10:33 pm
Título:

OK ...

El error mas importante (ya se ha señalado) se encuentra en la funcion "preguntar" en el ultimo codigo fuente publicado por astut:
Código:
bool Preguntar(char pregunta[250])
{
    char respuesta;
    printf("%s [S/N]", pregunta);
    scanf("%s" /* <-- AQUI -- */, &respuesta);
    if (respuesta == 115)
        return true;
    else
        return false;
}

Este se debe a la forma como funciona scanf: cuando en esta se utiliza el indicador de tipo "%s" la funcion lee una secuencia de caracteres (no importa cuantos) y los almacena a partir de la direccion en memoria indicada por el segundo argumento y que en nuestro caso es la direccion en memoria de la variable respuesta.

Aqui viene el problema: despues de esa secuencia de caracteres scanf almacena el caracter de fin de cadena (el '\0') para indicar (que mas) el fin de la cadena almacenada. Pero en nuestro caso en la direccion de memoria indicada (donde se almacena el objeto "respuesta") no se pueden almacenar dos (o mas) caracteres porque es de tipo char y por definicion solo puede almacenarse un unico caracter.

Para corregir esa funcion basta con utilizar el indicador de tipo "%c" ya que este lee un unico caracter y ya esta ejemplificado en el ultimo programa de Cheroky.

En cuanto al programa de Cheroky me parece que esta correcto salvo un minimo detalle: la funcion scanf (a diferencia de otras funciones como fgets) requiere se indique el numero de caracteres sin incluir el '\0', en otras palabras si se desea que el maximo sean 16 caracteres (incluyendo el '\0') a scanf se le debe utilizar con "%15s".

Un saludo
_________________
The capacity to learn is a gift;
The ability to learn is a skill;
The willingness to learn is a choice.
--
Rebec of Ginaz
Volver arriba
cheroky



Registrado: 22 Sep 2005
Mensajes: 1372
Ubicación: En ecx esperando un call

MensajePublicado: 22/10/2007 3:22 am
Título:

rir3760 escribió:
(a diferencia de otras funciones como fgets) requiere se indique el numero de caracteres sin incluir el '\0', en otras palabras si se desea que el maximo sean 16 caracteres (incluyendo el '\0') a scanf se le debe utilizar con "%15s".

Un pequeño detalle pero gran aclaración, efectivamente siempre pensé que este tipo de especificador de formato no era n-1 para alojar el ntbs.

Por cierto, cuando me refería al bucle infinito era una forma sarcástica de afirmar como era posible que fuera necesario tantos posts para que viera el error.


S2.
_________________
- Explícito es mejor que implícito.
- Simple es mejor que complejo.
- Complejo es mejor que complicado.
- Plano es mejor que anidado.
- Ralo es mejor que denso.
Volver arriba
daltomi



Registrado: 28 Abr 2007
Mensajes: 114
Ubicación: Argentina

MensajePublicado: 22/10/2007 5:26 am
Título:

daltomi escribió:
Faltaría notar si es el error que se produce en mi compilación, es el que da el fallo a astut.
Debia suponer que tendría que ser más específico. Yo me refiero, que dadas las correcciones expuestas e implementadas al código de astut, él y solo él, debía confirmar si el error continuaba.

En mi caso, hasta con las últimas correcciones la variable respuesta contiene un valor post-definido( no pre-definido o automaticamente como había dicho antes). Por lo tanto, repito, que puede o no, corresponder el falló que a mi se me presenta, el mismo que se le presentaría(futuro) a astus dadas las ultimas correcciones, en todo caso, disculpen por no esperar respuestas de nuestro compañero.

Colocando un breakpoint en la línea:
Código:

char respuesta;
printf("%s [S/N]", pregunta);
scanf("%c", &respuesta); <- breakpoint.

Como es de esperar, respuesta es indefinido. Luego, al permitir la ejecución de scanf, respuesta contiene el caracter siguiente al espacio en blanco("abc defg"), es decir, respuesta="d", no permitiendo asi, el ingreso por teclado de un valor, y siguiendo la lógica del programa, este termina, y sólo en algunos casos de depuración, un "thread", NO identificable como "main", puede ser la consola, termina con -1. Y he aquí, el problema del cuadro de mensaje que hace referencia astut, dado no por su IDE, sino por el SO, según me parece, típico mensaje del XP, por ejemplo.-

Saludos.
Volver arriba
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com