Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Ongelmia taulukoiden kanssa

Sivun loppuun

Kentti [23.12.2006 19:06:57]

#

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


int main() {

    int n;
    int i;
    int taulukko[5][5]    =     {{1, 3, 5, 7, 0},
                                 {2, 4, 6, 8, 0},
                                 {3, 5, 7, 9, 0},
                                 {4, 6, 8, 1, 0},
                                 {0, 0, 0, 0, 0}};

    for (n = 0; n < 5; n++) {

        for (i = 0; i < 5; i++) {

            taulukko[n][5] += taulukko[n][i];
            taulukko[5][i] += taulukko[n][i];
            }
    }

    printf("%d %d %d", taulukko[0][5], taulukko[5][0]);
    system("PAUSE > nul");

    return 0;
}

Tuossa tulosteena pitäisi olla "16 10", mutta tulokseksi tuleekin "18 4007288".

Ohjelman pitäisi siis laskea 2 ulotteisen taulukon jokaisen sarakkeen summa viimeiseen (viidenteen) sarakkeeseen ja jokaisen rivin summan viimeiseen alkioon, mutta jossain jotain vikana. Debuggaus ei sano mitään. Samanlainen virhe tuli, vaikka viimeisen sarakkeen ja rivin alusti arvoilla 1, joten ei ole nollasta kiinni...

Metabolix [23.12.2006 19:26:52]

#

Ensinnäkin, sinulla on kolme %d:tä, vaikka kaksi vain pitäisi tulostaa. Toiseksi, se viimeinen alkio on 4. eikä 5. (Viisi kohtaa: 0, 1, 2, 3 ja 4.)

Kentti [23.12.2006 20:09:04]

#

Viimeinen %d jäi vahingossa.

Mutta kiitos, nyt toimii :)

Prkl noiden alkioiden lukumäärän kanssa... :)


JA HYVÄÄ JOULUA KAIKILLE!!!

Draiz [23.12.2006 20:15:16]

#

Kentti kirjoitti:

JA HYVÄÄ JOULUA KAIKILLE!!!

Samoin. <3

tgunner [23.12.2006 21:26:46]

#

^Minultakin tuo sama. \o

Kentti [25.12.2006 12:38:25]

#

Nyt tuli toinen ongelma tietuetaulukon kanssa.

Koodi tekee valikon, jossa voi tyhjään, 10 alkioiseen tietuetaulukkoon syöttää tietoja ja niitä voi sitten hakea indeksillä. Kuitenkaan tuo indeksillä hakeminen ei palauta mitään.

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

struct TUOTE {

       char tuote[21];

};

int main() {

    TUOTE taulukko[10] = {{"Auto"}};
    unsigned short int valinta;
    int monesko_indeksi = 0;
    int indeksi;

    while (true) {
        system("CLS");
        printf("1) Lis\x84\x84 uusi tuote.\n2) Etsi tuote indeksill\x84.\n0) Sulje ohjelma.\n");
        scanf("%u", &valinta);

        switch(valinta) {

                        case 0:
                             exit(3);
                        break;

                        case 1:
                             system("CLS");
                             printf("Anna tuotteen nimi (max. 20 merkki\x84, ei v\x84lily\x94ntej\x84). Sen indeksi on %d\n", monesko_indeksi);
                             scanf("%s", &taulukko[monesko_indeksi].tuote);
                             monesko_indeksi++;
                        break;

                        case 2:
                             system("CLS");
                             puts("Hae tuote indeksill\x84. Indeksi:");
                             scanf("%d", &indeksi);
                             printf("\n\n\nHakemasi tuotteen nimi on %s.", taulukko[indeksi].tuote);
                             system("PAUSE > nul");
                        break;
        }
    }

    return 0;
}

Koodia ei ole kommentoitu, mutta se on melko yksinkertaista eikä sen toiminnan mielestäni kellekään pitäisi tuottaa vaikeuksia.

Minulla ei ole aavistustakaan, missä virhe olisi.

Metabolix [25.12.2006 12:43:21]

#

Ota tuotteen nimen lukemisesta & pois. Merkkitaulukko on jo itsessään osoitin merkkeihin.

Pekka Karjalainen [25.12.2006 14:12:30]

#

Onko tuo koodi C++:aa? Se ei käänny C-kääntäjällä, koska TUOTE- ja true-tunnuksia ei ole määritelty. Pitää lisätä:

typedef struct TUOTE TUOTE;
const int true = 1; /* ei välttämättä hyvä idea */

Näiden muunnosten jälkeen se kääntyy, mutta toiminnan kannalta Metabolixin mainitsema korjaus on tietenkin tarpeellinen. No, en varsinaisesti valita mistään. Jos Kentti ohjelmoi C++:lla ja tietää ohjelmoivansa sillä, niin sillä selvä.

Suosittelisin jättämään nuo system-kutsut pois, jotta ohjelmaasi voi testata paremmin myös muissa ympäristöissä, kuin DOS-lootassa. No, saapa ne itsekin pois.

Kukapa osaa selittää, miksi taulukon indeksiin nolla ei voi tallentaa haettavaa tietoa? Teenpä mitä vaan, niin se ei tulosta merkkijonoa indeksille nolla. Muille indekseille se tuntuu toimivan normaalisti. Testasin välillä 1-4 vain. (Tämä testaus oli C-kielenä käännetylle versiolle.)

LISÄYS: Jos siirrän taulukko-muuttujan määrittelyn main-funktion ulkopuolelle, se toimii paremmin. Nyt alkioon nollakin voi laittaa arvon, jonka se osaa tulostaa. Joku outo paikallisen muuttujan ominaisuus puree tässä, mutta en osaa nyt sanoa mikä ihme. Mystiseltä vaikuttaa.

Minulla on siis näin:

struct TUOTE {

       char tuote[21];

};
typedef struct TUOTE TUOTE;
const int true = 1;
TUOTE taulukko[10] = {0};

int main() {

Main on muuten sama kuin Kentillä, paitsi tuo & on poistettu ja taulukkoa ei määritellä mainin sisällä.

Kentti [25.12.2006 18:03:45]

#

Juu C++:lla ohjelmoin, ja ei auttanut kun poistin sen &-merkin pois siitä scanf("%s", &taulukko[monesko_indeksi].tuote)-kohdasta.

System-kutsut taas ovat sen takia, ettei tarvitse komentorivin kautta testailla. Vallan toimivia harjoitteluvaiheessa.

Edit: Nyt toimii, kun taulukon määrityksen laittoi globaaliksi. Mutta eikös sen pitäisi toimia, vaikka se olisi mainin sisällä?

Pekka Karjalainen [25.12.2006 18:30:29]

#

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

struct TUOTE {

       char tuote[21];

};
typedef struct TUOTE TUOTE;
const int true = 1;


int main() {

    TUOTE taulukko[10];
    unsigned short int valinta;
    int monesko_indeksi = 0;
    int indeksi;

    while (true) {
        system("CLS");
        printf("1) Lis\x84\x84 uusi tuote.\n2) Etsi tuote indeksill\x84.\n0) Sulje ohjelma.\n");
        scanf("%u", &valinta);

        switch(valinta) {

                        case 0:
                             exit(3);
                        break;

                        case 1:
                             system("CLS");
                             printf("Anna tuotteen nimi (max. 20 merkki\x84, ei v\x84lily\x94ntej\x84). Sen indeksi on %d\n", monesko_indeksi);
                             scanf("%s", taulukko[monesko_indeksi].tuote);
                             monesko_indeksi++;
                        break;

                        case 2:
                             system("CLS");
                             puts("Hae tuote indeksill\x84. Indeksi:");
                             scanf("%d", &indeksi);
                             printf("\n\n\nHakemasi tuotteen nimi on %s.", taulukko[indeksi].tuote);
                             system("PAUSE > nul");
                        break;
        }
    }

    return 0;
}

Kun käännän ylläolevan koodin MinGW-kääntäjällä ja ajan, niin taulukon indeksiin nolla ei mene arvoa. Yritin syöttää kolme eri merkkijonoa, jotka menivät indekseihin 0-2. Sen jälkeen yritin tulostaa niitä. Ensimmäinen oli tyhjä, mutta indekseillä 1 ja 2 arvot näkyivät.

Tyhjä tarkoittaa, että merkkijonon tulostus oli nollan merkin mittainen, ts. sitä ei ollut ollenkaan. Muut jonot tulivat syötetyn kaltaisina näkyviin.

En ymmärrä miksi näin. Globaali taulukko-muuttuja auttaa ongelmaan. En ymmärrä sitäkään, miksi juuri se auttaa.


C:\TEMP>gcc --version
gcc (GCC) 3.4.2 (mingw-special)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Käänsin pelkästään optioilla gcc ct.c -o ct2.exe.

Täytyy varmaan katsoa debuggerilla, että mitä siellä muistissa oikein luuraa. En vain nyt tajua, mikä tuon voisi aiheuttaa.

Ja tosiaan, käytän C-kieltä itse. Voisin kokeilla C++:llakin, kunhan kinkun ahmimiselta jaksan.

LISÄYS: Niitä varoituksiakin kannattaa katsella:

C:\TEMP>gcc ct.c -o ct2.exe -Wall
ct.c: In function `main':
ct.c:23: warning: unsigned int format, different type arg (arg 2)

Mutta tuo ei selitä pulmaamme.

LISÄYS 2: Hehe, se selittää sen sittenkin. Eihän tätä C-kieltä voi ihminen osata...

Koska valinta-muuttujan tyyppi on väärä, kirjoittaa scanf-funktio TUOTE-taulukon päälle, kun sitä valinta-muuttujan arvoa luetaan. Vaihda näin:

int main() {

    TUOTE taulukko[10];
    int valinta; /* HOX */
    int monesko_indeksi = 0;
    int indeksi;

    while (true) {
        system("CLS");
        printf("1) Lis\x84\x84 uusi tuote.\n2) Etsi tuote indeksill\x84.\n0) Sulje ohjelma.\n");
        scanf("%d", &valinta); /* HOX */

Ja muu osa kuten ennen tai yllä. Sitten toimii, ainakin minulla.

Opetus? Kannattaa käyttää sitä iostreamia!


Sivun alkuun

Vastaus

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

Tietoa sivustosta