2

Soy nuevo en el mundo de la programación, apenas estoy comenzando, y resulta que hoy al ejecutar un programa sencillo me salto "prueba del programa.exe ha dejado de funcionar". No entiendo porque me salta esto, nunca me había pasado anteriormente y parece que el problema es precisamente con esta parte del código. alguien me podría explicar que pasa? Desde ya, muchas gracias.

#include<stdio.h>
int main(){
    int dia;
    int auxd;
    int contd;

contd=0;
auxd=1;
    do{
        printf("ingrese dia: ");    scanf("%i",dia);

    if(auxd==dia){
        contd++;
        if (contd>4){
            printf(" el dia %i ha pasado las 4 consultas",dia);
        }
    }
    else{
        auxd=dia;
        contd=0;
    }
}while  (dia != 0);
 return 0;

}
eferion
  • 49,291
  • 5
  • 30
  • 72

2 Answers2

3

Como te indican en los comentarios, scanf necesita un puntero para poder almacenar los datos introducidos por el usuario. Sin embargo, si etiquetas la pregunta como C++ lo lógico es que pases a usar código C++ y dejes de programar en C.

También sería recomendable que tabulases correctamente el código. Tu programa de menos de 30 líneas ya empieza a ser complicado de leer al estar mal tabulado... cuando tengas que hacer uno de 300 líneas te va a doler, en serio.

#include<iostream>

int main(){
  int contd = 0;
  int auxd = 0;
  int dia;

  do{
    std::cout << "ingrese dia: ";
    std::cin >> dia;

    if(auxd==dia){
      contd++;

      if (contd>4){
        std::cout << " el dia " << dia << " ha pasado las 4 consultas";
      }
    }
    else{
      auxd=dia;
      contd=0;
    }
  }while (dia != 0);
  return 0;
}
eferion
  • 49,291
  • 5
  • 30
  • 72
2

Ya se ha indicado en comentarios y en la respuesta de eferion que el detonante de tu fallo es usar mal la función scanf. Me uno al consejo del resto de usuarios al recomendarte que leas el manual de dicha función; sin embargo saber dónde falla el programa no explica por qué falla. La explicación es algo compleja.


La función scanf forma parte de las librerías de y por ello sigue las normas del lenguaje C en su funcionamiento; una de las limitaciones de este lenguaje es la ausencia de referencias1 y esta limitación hace que para modificar una variable fuera de su ámbito sea necesario pasar la dirección de memoria de la misma.

Dado que has pasado "%i" como formato de lectura, la función scanf esperará escribir en un entero (int) y por ello asume que recibirá un puntero a entero. Insisto en el concepto de que scanf asume que recibirá un puntero a entero, esta función (de las librerías de C) no tiene manera de comprobar que el tipo de dato facilitado coincida con el tipo de dato esperado2 y por ello asume que lo va a ser; es trabajo del programador asegurar que se cumpla esta precondición3.

En tu código, fallaste en tu responsabilidad como programador de asegurar la precondición esperada por scanf, así que asumió que el entero que estabas pasando como parámetro era un puntero a entero. En tu código podemos ver que no inicializas la variable dia, según las normas de inicialización de C++ ésto dejará dicha variable con un valor indeterminado y ese valor será lo que scanf interprete como una dirección de memoria que al intentar escribir en ella se producirá una violación de segmento y el sistema operativo te informará de que tu programa.exe ha dejado de funcionar.


  1. Puedes conocer la diferencia entre puntero y referencia en este hilo.
  2. En otras palabras: no puede garantizar la seguridad de los tipos.
  3. Por estos motivos la función scanf se considera como poco segura, propensa a errores y un posible agujero de seguridad en el sistema, incluso existen tutoriales para sacar provecho de las vulnerabilidades que provoca la función scanf. Por ello en C++ se desaconseja su uso y en C se aconseja usar alternativas seguras como sscanf (secure scanf).
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
  • Quería centrarme en el por qué falla, no en los demás problemas que tiene la pregunta (indentación, variables no inicializadas, cabeceras inadecuadas) y aún queriendo centrarme, mi respuesta es muy dispersa. – PaperBirdMaster Aug 20 '18 at 07:38
  • 1
    Si, en ciertos casos es complicado dar una respuesta completa. Por cierto, bienvenido de tu pausa vacacional :) – eferion Aug 20 '18 at 07:39