Apua c-ohjelman kanssa!

aloitteleva_kdr

Teen viopessa c-ohjelmoinnin harjoituksia ja eräs tehtävä tuottaa hieman päänvaivaa. Ensimmäiset kaksi viopen testeistä menevät läpi mutta kolmas, joka on piilotettu feilaa.. Osaisiko joku jeesata ja kertoa mitä pitäisi muuttaa, että ohjelma toimisi. En siis tiedä mitä nimiä viope syöttää ohjelmalle, mutta lopputulos on seuraava:

Tiedoston luettelo.txt sisältö:

3
Keijo Kojootti 050-3500980
Brian Kottarainen 040-3980982
Brian Kottarainen 040-3980982

Kun tiedoston pitäisi olla seuraavanlainen:

3
Keijo Kojootti 050-3500980
Brian Kottarainen 040-3980982
Brita Kottarainen 05-4567393

Eli ongelma liittyy varmaankin tohon että molemmat Brian ja Brita alkaa samoilla kirjaimilla ja sukunimi on sama. En vaan keksi mitä pitäisi muuttaa. Pistän alle tehtävänannon ja lopuksi vielä koodin.

Tehtävänanto:
Puhelinluettelo - henkilön tietojen poistaminen ohjelmointitehtävä 3/3
Tee ohjelma, jolla voidaan poistaa luettelosta tietyn henkilön tiedot. Ohjelma kysyy ensin etunimen ja tämän jälkeen sukunimen. Ohjelma tarkistaa, löytyykö henkilön tiedot. Mikäli henkilö löytyy luettelosta, tiedot poistetaan. Muuten tulostetaan virheilmoitus "Etsimääsi henkilöä ei löytynyt luettelosta.".

Vihje:
Ennen kuin ryhdyt laatimaan varsinaista koodia, sinun kannattaa suunnitella ohjelma hyvin. Rakenteiden käyttäminen voi helpottaa tehtävää. Päivitetyn listan tallentaminen mitä ilmeisimmin tuhoaa aikaisemmat tiedot tiedostosta luettelo.txt.

Nimitietojen vertailu onnistuu c-kielen funktiolla strcmp(), joka löytyy kirjastotiedostosta string.h. Voit tutustua funktion käyttöön c-manuaalissa.
Esimerkkitulostus


Anna etunimi:Timo
Anna sukunimi:Timpuri
Tiedot poistettu luettelosta.

10

2459

    Vastaukset 10

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • aloitteleva_kdr

      KOODI:

      #include
      #include
      #include

      struct henkilo {
      char enimi[21];
      char snimi[21];
      char puh[21];
      };

      const char rekisteri[] = "luettelo.txt";

      char* TiedonKopiointi(char*out, char*in, unsigned koko)
      {
      char* pc, *pc2;
      unsigned j;
      memset(out, 0, koko);
      pc = in;
      pc2 = out;
      for(j = koko; j && *pc != ' ' && *pc != '\n'; --j){
      *pc2 = *pc;
      pc2 ;
      pc ;
      }
      return pc;
      }

      struct henkilo* TaytaTietue(char*buffer, struct henkilo*phenk)
      {
      char* pc;
      pc = buffer;
      pc = TiedonKopiointi(phenk->enimi, pc, 21);
      pc = TiedonKopiointi(phenk->snimi, pc, 21);
      pc = TiedonKopiointi(phenk->puh, pc, 21);
      return phenk;
      }

      unsigned LueTiedostoMuistiin(struct henkilo*henkilo_lista)
      {
      char buffer[sizeof(struct henkilo)];
      FILE *tiedosto;
      int hlomaara = 0;
      struct henkilo* phenk;
      long i;
      if ((tiedosto = fopen(rekisteri, "r")) != NULL) {
      fgets(buffer, 4, tiedosto);
      hlomaara = atoi(buffer);
      if (hlomaara >= 50) {
      printf("Korkeintaan %d tietuetta", 50);
      fclose(tiedosto);
      return -1;
      }
      for(i = 1, phenk = henkilo_lista; i i)
      return phenk;
      else if(poistettava != i){ /*Viimeistä poistetaan*/
      phenk1 = henkilo_lista;
      phenk1 = (poistettava - 1); /*Poistettavan kohdalle*/
      phenk2 = phenk1;
      phenk2 ; /*Ensimmäisen siirrettävän kohdalle*/
      /*Siirretään loppuja pykälällä*/
      pc = (char*)(void*)phenk2;
      pc2 = (char*)(void*)phenk;
      memcpy(phenk1, phenk2, pc - pc2);
      }
      *hlomaara = i - 1;
      return --phenk;
      }

      unsigned TallennaTiedostoon(struct henkilo* phenk, unsigned maara)
      {
      FILE *tiedosto;
      unsigned i;
      if ((tiedosto = fopen(rekisteri, "w")) == NULL) { /*Uuden tiedoston luonti*/
      printf("Virhe tiedoston avaamisessa.");
      return 1;
      }
      fprintf(tiedosto, "%d\n", maara); /*Kirjoitettavien määrä tiedoston alkuun*/
      for(i = maara; i; --i){
      fprintf(tiedosto,"%s %s %s\n", phenk->enimi, phenk->snimi, phenk->puh);
      phenk ;
      }
      fclose(tiedosto);
      return 0;
      }

      int main(void)
      {
      struct henkilo henkilo_lista[50];
      unsigned hlomaara, poistettava;
      struct henkilo* phenk;
      unsigned i, j;
      struct henkilo etsittavahlo;

      hlomaara = LueTiedostoMuistiin(henkilo_lista);
      if(hlomaara > (unsigned)-1)
      return 1;

      printf("Anna etunimi:");
      scanf("%s", etsittavahlo.enimi);
      printf("Anna sukunimi:");
      scanf("%s", etsittavahlo.snimi);

      for(i = 0, j = 0, phenk = henkilo_lista; i < hlomaara ; phenk , i){
      if(strcmp(phenk->enimi, etsittavahlo.enimi) == 0) {
      if(strcmp(phenk->snimi, etsittavahlo.snimi) == 0) {
      PoistaHenkilo(henkilo_lista, phenk, &hlomaara, i 1);
      printf("Tiedot poistettu luettelosta.");
      j = 1;
      break;
      }
      }
      }
      if(!j)
      printf("Etsimääsi henkilöä ei löytynyt luettelosta.");

      /*Tallennetaan lista tiedostoon*/
      TallennaTiedostoon(henkilo_lista, hlomaara);

      return 0;
      }

    • johanonnistuu.

      tuttujuttu, et käytä IBM ASCII-järjestelmää, jossa on kaikki ääkköset ja öökköset, vaan uutta "muka uutta (25v vanhaa)", tai toinen vaihtoehto on nämä "whitespacet", eli.. joka tapauksessa kirjaimet toimivat, mutta huono uusi näppäinjärjestelmä.

      Tuon voi kyllä kiertää jos osaa, laitat vaan käyttöjärjestelmään että IBM 256-letter ASCII.

      • jf394yfgefok4

        Mutta voisin mainita tuosta sinun c-koodista... näyttääpä sotkuiselta, koneella tehtyä jotain :) tuonkin voisit korjata pääfunktiossa: "void main(void)", ja palautus "return ;"


      • sdfsfsdfs54353
        jf394yfgefok4 kirjoitti:

        Mutta voisin mainita tuosta sinun c-koodista... näyttääpä sotkuiselta, koneella tehtyä jotain :) tuonkin voisit korjata pääfunktiossa: "void main(void)", ja palautus "return ;"

        Kai tuo oli vitsi.

        void main(void); on totaalisen väärin.

        int main(void); on oikea standardin mukainen menettely.


    • idomaattinen9

      Ei ole vaan täysin oikein :)
      ei oteta vastaan mitään, eikä palauteta mitään koko ohjelmasta :)

      Muuten näyttää tuo hyvälle ihan kun tarkemmin katoin, mutta miksi palautat koko ohjelmasta mitään, kun kerran jo tallennat tulokset tiedostoon???

      siitä tämä void-juttu.

      Tuo puuttuu sulla tiedostoon tulostamisesta: "\r \n", kumpikin pitää olla peräkkäin..

    • tyhmättyhjätincludet

      Myöskin jos tuo on C/C kääntäjä mitä käytät, niin lisätä noiden tyhjien include-tiedostojen tilalle: "using namespace std;"

    • noohhhhhflds43lf43

      void main(void), sitten return (void); täysin oikein.

      • sdfsdfsdfsd

        Tuo on totaalisen väärin.

        Ensinnäkin standardin mukaan mainin täytyy olla aina INT tyyppinen ja mainin täytyy aina palauttaa INT arvo.

        Tämä siksi että käyttiksen puolella voidaan havaita mitä ohjelma palauttaa ja sen perusteella päätellä onnistuiko ohjelman suoritus ja mitä virheitä ohjelmassa tapahtui.

        Tuo void main(void); käytäntö on jostian kivikaudelta kun C:n standardi ei ollut vielä kehittynyt.

        Muistakaa AINA: "int main(void)" tai "int main(int argc, char *argv[])"
        Nämä ovat ainoat standardinmukaiset vaihtoehdot puhtaassa C:ssä.

        Toki myös on winmaineja muita entrypointteja mutta ne toteuttavat saman kaavan.


    • Eiköhän opiskelun tarkoitus ole itse oppia näin yksinkertainen ohjelma, eikä yrittää saada joku netistä korjaamaan ohjelmaasi. Vilkaisepa sitä toisen kerran paremmin. Kyllä se syy selkeästi on koodissasi.

      Se mitä standardia main function kanssa käytetään on täysin jonni joutavaa kiistelyä, joka viittaa siihen, että kiistelijä on joko kaikkea vihaava ideologi tai melko kokematon ohjelmoija. Ei ole merkitystä, millä standardilla se on kirjoitettu, kunhan se toimii oikein.

      • tgdgdfgdfg

        Ei ole jonninjoutavaa.

        Ensinnäkin miksi opetalla huonoja ja VÄÄRIÄ ohjelmointitapoja kun voi samalla vaivalla opetella asian oikein.

        Lisäksi nimenomaan "void main()" version kanssa tukee oikeasti ongelmiakin käyttisalustoilla. Sulautetussa void main(); voi olla ok jos alusta ei vaadi / tarkista mitä main palauttaa.


        Tässä syitä käyttää standardinmukaista oikeaoppista int mainia.

        1. Koska se on standardi

        2. Koska ohjelman aloitus rutiinit jotka kutsuvat mainia saattavat olettaa tai olettavat että mainin palautusarvo asetetaan pinoon. Jos main funktio ei tee tätä, saattaa ohjelman lopetus rutiinin pino vikaantua / korruptoitua ja aiheuttaa määrittelemätöntä toimintaa tai kaatumisia.

        3. Koska standardista poikkeava maini saattaa palauttaa aivan sattumanvaraisen arvon kutsuvalle käyttikselle. Tämän takia ei pystytä tarkistamaan esimerkiki ohjelman vikakoodia. Lisäksi makefilet ja vastaavat luottavat ohjelmien palautusarvoihin toiminnoissaan.

        4. Koska mainin palauttama kokonaislukua käytetään ohjelman tilan tarkastuun (onnistunut suoritus, virhetilanne, virhekoodi).


    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Huomenta

      Sinulle! Olen miettinyt sinua paljon yön aikana. 🫂
      Ikävä
      66
      1070
    2. Mitä ihmettä pitäisi tapahtua

      Että me kohdataan ja saadaan tämä tilanne etenemään?
      Ikävä
      69
      762
    3. Viesti sinulle

      Tiedät että tunteet ja ajatukset ja meillä on vahva yhteys mistä molemmat tiedetään. Odotan sinua ☀️
      Ikävä
      40
      736
    4. Jos mies naisen prinsessakohtelu

      on sinulle liikaa, älä valitse prinsessaa 🦋🧚🏼‍♀️👸🏼
      Ikävä
      149
      716
    5. Olen kironnut sinut alimpaan helvettiin

      Hyvää matkaa.
      Ikävä
      72
      697
    6. Miksi meille jäi

      Niin huonot välit vaikka meistä kumpikaan ei ole tunteilleen mitään voinut. Ehkä se kohtalo on sitä mieltä ettei kuitenk
      Ikävä
      37
      665
    7. Mitä sinulle on tapahtunut lapsena

      Kun olet noin sairas päästäsi? Pikkupojalle ( Miehen kehossa)
      Ikävä
      76
      623
    8. Ikävö sinua nainen!

      Rakastan sua! ❤️💛❤️💜🧡🧡💚🤎:💜💜❤️
      Ikävä
      45
      596
    9. Tunteiden käsittely kertoo ihmisestä.

      Kun puhutaan "tavallisesta" ihmisestä, joka on suht tasapainoinen eläjä, niin puhutaan oikeastaan taitavasta tunteiden k
      Sinkut
      201
      559
    10. Rakas, rakkaampi, rakkain

      Olen tullut siihen johtopäätökseen, ettei minun kannata rakastaa. Kaikki joita olen koskaan rakastanut vain kohtelevat m
      Sinkut
      111
      547
    11. Haluan purkaa vielä tuntemuksia

      Tykkään sinusta kovin paljon❤️ olen surullinen tilanteestasi ja siitä mitä me olemme yhdessä joutuneet kokemaan. Tämä ei
      Ikävä
      19
      530
    12. Ketä ajattelen

      kun mietin, mitä sinulle kuuluu? En tunne sinua oikeasti, ja se on ehkä hyvä, koska jos tietäisin enemmän, se varmaan v
      Ikävä
      18
      480
    13. Kyllä tiedän sun

      Likaiset pelit selän takana
      Ikävä
      47
      442
    14. Onko tuo joku katkera nainen oikeasti

      Joka sinua syyttää?
      Ikävä
      81
      436
    15. Sara Sieppi ja hissi tänään

      Voi helvetin helvetti. Nytkö tätä naikkosta täytyy palvoa ja antaa etuoikeus hissiin, kun hän on vääntänyt kakaran maail
      Kotimaiset julkkisjuorut
      112
      435
    16. Pilkettä sunnuntain silmässä

      😉 Jos tästä ketjusta löytyisi yksi ihminen, joka saisi sut hymyilemään tänään… Millainen hän olisi? Ei tarvitse kerto
      Sinkut
      64
      426
    17. Työttömän miehen ihmisarvo

      ..parisuhdemarkkinoilla on olematon. Työtön mies on naisille ihmisjätettä, varsinkin jos sattuu olemaan vielä kunnolline
      Sinkut
      102
      404
    18. Jos olet aidosti jostakin

      kiinnostunut, niin yrität myös lähestyä irl. 😁
      Ikävä
      52
      393
    19. Tiedätkö kun on

      Ikävä sinua melko usein.
      Ikävä
      17
      392
    20. YLINEN pilaa Ähtärin mahdollisuudet.

      Vuodeosastopäätös jossa Nina Ylinen (sdp) äänesti niiden lopettamisen puolesta, hoitajille potkut ja silti arviointimene
      Ähtäri
      23
      383
    Aihe