Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Laskinohjelmassa ongelma

Aloittelija2 [26.12.2004 19:23:01]

#

Ohjelma valittaa tällaista:
fatal error C1004: unexpected end of file found

Mistähän mahtaa johtua? En keksi millään syytä ohjelman valitukseen.

Koodi:

#include <stdio.h>

int main(void){

int painettu_numero;
int x, y, summa;
int o, p, erotus;
int r, t, tulo;
int valinta;

    printf("1: kahden luvun summa\n");
printf("2: kahden luvun erotus\n");
printf("3: kahden luvun tulo\n");
 printf("<0: ohjelman lopetus\n");
    printf("Valitse laskutoimitus:");
scanf("%d", &valinta);
    if(valinta < 0) {
printf("Ohjelman lopetus");

    scanf("%d", &painettu_numero);

switch(painettu_numero)
       {
          case 1:
          {
            printf("Syötä ensimmäinen luku:");
scanf("%d", &x);
printf("Syötä toinen luku:");
scanf("%d", &y);

    summa=x+y;


            printf("%d + %d = %d", x, y, summa);

            break;
          }
          case 2:
          {
            printf("\n Syötä ensimmäinen luku:");
scanf("%d", &o);
printf("Syötä toinen luku:");
scanf("%d", &p);

    erotus=o-p;


            printf("%d - %d = %d", o, p, erotus);

            break;
          }
          case 3:
          {
            printf("\n Syötä ensimmäinen luku:");
scanf("%d", &r);
printf("Syötä toinen luku:");
scanf("%d", &t);

    tulo=r*t;


            printf("%d * %d = %d", r, t, tulo);
            break;
          }
}


       return 0;
     }

Antti Laaksonen [26.12.2004 19:40:50]

#

Virhe johtuu siitä, että aaltosulku on jäänyt auki if-rivillä. Vasta tiedoston lopussa C-kääntäjä äkkää, että jotain on vialla. Kunnollinen sisennys olisi paljastanut tämän virheen.

Muita vinkkejä:
- Lue laskutoimituksen valinta vain kerran.
- Kankean switchin asemesta if-toteutus on yleensä parempi.
- Voit lukea numerot kussakin tapauksessa samoihin muuttujiin. Laskutoimituksesta riippumatta luku tapahtuu samalla tavalla, eli se täytyy kirjoittaa vain kerran.
- Summaa, erotusta ja tuloa ei tarvitse panna omaan muuttujaan, vaan laskutoimituksen voi suoraan kirjoittaa printf-funktion parametreihin.

Aloittelija2 [26.12.2004 20:00:45]

#

Nyt koodi on tällainen. Toimii mutta ei lopeta ohjelmaa esim. luvulla -1. Missä vika?

#include <stdio.h>

int main(void){

int painettu_numero;
int x, y, summa;
int o, p, erotus;
int r, t, tulo;
int valinta;

    printf("1: kahden luvun summa\n");
printf("2: kahden luvun erotus\n");
printf("3: kahden luvun tulo\n");
 printf("<0: ohjelman lopetus\n");
printf("Valitse laskutoimitus:");

    scanf("%d", &painettu_numero);

switch(painettu_numero)
       {
          case 1:
          {
            printf("Syötä ensimmäinen luku:");
scanf("%d", &x);
printf("Syötä toinen luku:");
scanf("%d", &y);

    summa=x+y;


            printf("%d + %d = %d\n", x, y, summa);

            break;
          }
          case 2:
          {
            printf("\n Syötä ensimmäinen luku:");
scanf("%d", &o);
printf("Syötä toinen luku:");
scanf("%d", &p);

    erotus=o-p;


            printf("%d - %d = %d\n", o, p, erotus);

            break;
          }
          case 3:
          {
            printf("\n Syötä ensimmäinen luku:");
scanf("%d", &r);
printf("Syötä toinen luku:");
scanf("%d", &t);

    tulo=r*t;


            printf("%d * %d = %d\n", r, t, tulo);
            break;
          }
}

      {
       return main();
}}

Blaze [26.12.2004 21:02:06]

#

No ei tietenkään lopeta, kun et oo koodannu sitä siihen. Tee lopetukselle oma case.

Ja tuo sisennystyylis on kyllä melkosen... omaperänen.

Metabolix [26.12.2004 21:45:11]

#

Mitä kummaa, Blaze? Siinä ei ole casea lopetukselle, joten ohjelman suoritus menee koko switchin ohi, no problem. Vai ymmärsinkö kommenttisi väärin?

Omaperäistä tuossa on se, että lopussa on return main(). Tuo vain aloittaa ohjelman suorituksen alusta (tavallaan) ja varaa samalla muuttujille yhä lisää muistia. Laita siis siihen return 0;
Tällöin on helpompaa lisätä ohjelmaan esim. koko ohjelman kattava while-silmukka, jota toistetaan, kunnes pitää lopettaa.

Lisäksi kannattaa lisätä tuohon ennen switch-rakennetta ohjelman lopettava lause:
if (painettu_numero < 0) return 0;

Sisennystä voisi tosiaan opetella.

Edit:
Huomautan vielä, että on aivan järjetöntä käyttää eri muuttujia eri toimituksissa (x+y, o-p, r*t). voit ihan hyvin käyttää kaikissa x:ää ja y:tä.
Lisäksi on aika tyhmää edes kysyä lukuja aina erikseen. Jos vaikka muuttaisit järjestystä:
1. Tarkista, onko valinta virheellinen tai pitääkö ohjelma lopettaa
2. Kysy kaksi lukua
3. Katso, mikä toimitus pitää tehdä ja tee se.
Mahduttaisin tuon ohjelman noin 25 riville kaikki includet ja muut mukaan lukien, kunnon sisennyksin ja ilman turhia sotkuja.

Blaze [26.12.2004 22:50:45]

#

Metabolix kirjoitti:

Mitä kummaa, Blaze? Siinä ei ole casea lopetukselle, joten ohjelman suoritus menee koko switchin ohi

Niin, ja switchin jälkeen tulee return main(), joka alottaa saman taas alusta :)
Oletin, että se on siellä tarkotuksella, jolloin tuossa on ikuinen looppi, eikä mitään, millä siitä pääsee pois.

Metabolix [27.12.2004 16:34:18]

#

Niin, ei voi tietää oliko se siinä tarkoituksella vai vahingossa. Se on joka tapauksessa äärimmäisen huono ratkaisu, kun nuo muuttujat ovat paikallisia ja tuosta seuraa vain puumainen rakenne, joka varaa koko ajan lisää muistia.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta