merkkijono ja funktio

++++++

Miten tehdään funktio, joka palautaa arvonaan merkkijonon?? Haluaisin lukea käyttäjältä merkkijonon funktiolla ja sijottaa sen tietueeseen.
Olen yrittänyt näin:

char *anna_teksti(void) {

char lueteksti[TEKSTI_MAX];
fgets(lueteksti, TEKSTI_MAX, stdin);

return lueteksti;
}
------------
strcpy(Tietue.teksti, anna_teksti());

Herjaa kuitenkin, että koittaa palauttaa paikallisen muuttujan osoitteen.
Olisiko kenelläkään heittää neuvoa???

13

886

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • Nimetön

      Toi koodi kääntyi ja toimi mulla mutta se antoi warning:n.
      Oletan että tämä johtuu siitä että palautat pointerin joka osoitaa merkkijonoon, mutta kun funktiosta poistutaan niin merkijonpon varaama muisti vapautetaa. Joten laita sana static char lueteksti[TEKSTI_MAX] niin merkijonon varaamaa muistia ei vapauteta.

      • +++++++++++

        Warningin se mullakin vaan heitti ja ongelma korjautui tolla staticilla. Onkohan muita tapoja ratkaista tämä?
        Kiitoksia vastauksesta.


      • Nimetön
        +++++++++++ kirjoitti:

        Warningin se mullakin vaan heitti ja ongelma korjautui tolla staticilla. Onkohan muita tapoja ratkaista tämä?
        Kiitoksia vastauksesta.

        Eipä taida olla, paitsi jollet määrittele luetekstiä globaaliksi.

        Esim.

        char lueteksti[TEKSTI_MAX];

        char *anna_teksti(void) {
        ...fgets(lueteksti, TEKSTI_MAX, stdin);
        ...return lueteksti;
        }

        main() {
        ...strcpy(Tietue.teksti, anna_teksti());
        }

        Taikka jos välität sen funktiolle ja palautat sen.

        Esim.

        char *anna_teksti(char *lueteksti) {
        ...fgets(lueteksti, TEKSTI_MAX, stdin);
        ...return lueteksti;
        }

        main() {
        ...char lueteksti[TEKSTI_MAX];
        ...strcpy(Tietue.teksti, anna_teksti(lueteksti));
        }

        Taikka jos et halua palauttaa mitään

        Esim.

        void *anna_teksti(char *lueteksti) {
        ...fgets(lueteksti, TEKSTI_MAX, stdin);
        }

        main() {
        ...char lueteksti[TEKSTI_MAX];
        ...anna_teksti(lueteksti)
        ...strcpy(Tietue.teksti, lueteksti);
        }


      • .py
        +++++++++++ kirjoitti:

        Warningin se mullakin vaan heitti ja ongelma korjautui tolla staticilla. Onkohan muita tapoja ratkaista tämä?
        Kiitoksia vastauksesta.

        Static-ratkaisua tai globaalia muuttujaa käyttäessäsi kannattaa muistaa, että kaikki luetut merkkijonot tallentuvat samaan muistipaikkaan. Et siis voi ihan suoraviivaisesti ohjelmaa, joka lukisi kaksi merkkijonoa ja kertoisi olivatko ne samat.

        Viisaampaa olisi varata muisti malloc-käskyllä ja joko antaa funktiolle osoite varattuun muistiin ("tallenna se käyttäjän syöte tänne") tai hoitaa muistinvaraus funktion sisällä, jolloin funktio palauttaa osoitteen varaamaansa muistialueeseen.


      • +++++
        .py kirjoitti:

        Static-ratkaisua tai globaalia muuttujaa käyttäessäsi kannattaa muistaa, että kaikki luetut merkkijonot tallentuvat samaan muistipaikkaan. Et siis voi ihan suoraviivaisesti ohjelmaa, joka lukisi kaksi merkkijonoa ja kertoisi olivatko ne samat.

        Viisaampaa olisi varata muisti malloc-käskyllä ja joko antaa funktiolle osoite varattuun muistiin ("tallenna se käyttäjän syöte tänne") tai hoitaa muistinvaraus funktion sisällä, jolloin funktio palauttaa osoitteen varaamaansa muistialueeseen.

        Toi static ratkaisu ajaa kyllä tarkoituksensa tässä tapauksessa, mutta taidan ainakin kokeilumielessä
        harjoitella tuota malloc juttua, kunhan löydän siittä jotain juttua jostain.

        Olis taas kysymyskin....
        Taulukossa on tietueita
        typedef struct {
        time_t aika;
        char teksti[TEKSTI_MAX];
        } Tietue;
        ja haluaisin "nollata" jonkin kohdan taulukosta.
        Onko järkevää/voiko tehdä esim. vakio jossa tietueen kentät ovat tyhjiä???
        Miten tällainen vakio määritellään??
        Olen yrittänyt, mutta en onnistu.


    • hmmmmss

      Toinen ja ehkäpä parempi vaihtoehto on, että käytät C :aa. Ja sieltä erityisesti "string"-tyyppistä muuttujaa, jonka voi antaa function paluuarvona.

      • Ihmettelijä II

        Miten C /käyttäjä hoitaan muistin vapautuksen jos käyttää string tyyppiä? Eikö static:a tarvita enää?


      • *BSD
        Ihmettelijä II kirjoitti:

        Miten C /käyttäjä hoitaan muistin vapautuksen jos käyttää string tyyppiä? Eikö static:a tarvita enää?

        C :ssa on olemassa destructori (string::~string()), joka tuon tekee. Lisäksi kopiointi semantiikka on siellä mahdollista korvata omalla (vrt. copy constructor), jonka string-luokka nimenomaan tekee.

        Suomeksi: muistin vapautuksen hoitaa destruktori (jos string muuttuja palautetaan funktiosta, eli on pinossa sijaitseva muuttuja).


      • Ihmettelijä II
        *BSD kirjoitti:

        C :ssa on olemassa destructori (string::~string()), joka tuon tekee. Lisäksi kopiointi semantiikka on siellä mahdollista korvata omalla (vrt. copy constructor), jonka string-luokka nimenomaan tekee.

        Suomeksi: muistin vapautuksen hoitaa destruktori (jos string muuttuja palautetaan funktiosta, eli on pinossa sijaitseva muuttuja).

        Niinpäs se taisi olla (Unohtaa nämä asiat kun ei ole koodannut pitkään aikaan). Voisiko viellä joku hieman opettaa minua.

        Miten on static sanan laita, ilmeisesti se tarvitaan jos aikoo palauttaa paikallisen olion.
        Mitä kopionti semantiikka tarkoittaa?


      • *BSD
        Ihmettelijä II kirjoitti:

        Niinpäs se taisi olla (Unohtaa nämä asiat kun ei ole koodannut pitkään aikaan). Voisiko viellä joku hieman opettaa minua.

        Miten on static sanan laita, ilmeisesti se tarvitaan jos aikoo palauttaa paikallisen olion.
        Mitä kopionti semantiikka tarkoittaa?

        static tarkoittaa funktiossa sitä, että muuttuja varataan bss (tai data) segmentistä. Eli se käyttäytyy kuin globaali-muuttuja mutta ainoastaan kys. funktio sitä käyttää.

        Jos haluat palauttaa paikallisen olion niin silloin sen on parempi olla static (ks. myös edelliset keskustelut).

        Kopiointi semantiikka tuossa tapauksessa tarkoittaa, että voit muuttaa luokan käyttäytymistä kun se kopioidaan (ks. kopio-konstruktori).

        Kun kerran käytät C :aa niin tuollaisista asioista ei tarvitse huolehtia vaan string-luokka toimii juuri kuten pitääkin.

        string f()
        {
        ' return "foozyxxy";
        }

        ...

        string s = f();
        cout


    • Builder

      Tutki tätä."Antaa" merkkitaulukon osoitteen
      Tässä ei käytetä palautusarvoja.
      Funktio ei voi palauttaa char *stringiä
      Muutoin pätevät mitä kaverit ovat aiemmin sanoneet
      Mitähän kätkettyjä virheitä tässä voisi olla???
      Voit sitten itse sijoittaa tuloksen mihin haluat.

      #include
      #include
      #include
      #include
      #pragma hdrstop
      //---------------------------------------------------------------------------
      #pragma argsused
      void stringi(char nimi[]);
      int main(void)
      {
      char ss[800];
      char *x=strcpy(ss,"W");
      stringi(x);
      printf("%s",x);
      getch();
      return 0;
      }
      //**************************************************************************
      void stringi(char nimi[])
      {
      char nimi2[800];
      gets(nimi2);
      strcpy(nimi,nimi2);
      }

      • Kun tuolle annetaan yli 800 merkkiä, niin segfaultin saaminen on mitä todennäköisempää. Lue aina maksimissaan vain varatun muistialueen määrä merkkejä, ja muista varata tilaa vielä NULL-merkille.

        mainin strcpy on ihan turha, koska seuraavan rivin kutsu ylikirjoittaa x:n.

        Alemmassa funktiossa on myös kiinteä maksiarvo. Tuollaisen ylläpidettävyys menee vaikeaksi, jos jokaiseen uuteen paikkaan pitää muistaa aina laittaa joku arvo. Käytä #defineä tai mielummin varaa muisti dynaamisesti mallocilla. Dynaamisen muistin avulla voit palauttaa myös char * -tyyppisiä muuttujia (luonnollisesti se muisti pitää muistaa vapauttaakin free:llä).

        gets:n käyttöä kannattaa välttää, sillä se ei tarkista mahtuuko syötetty teksti sille annettuun muuttujaan vai ei.

        Samaten strcpy:n sijaan kannattaa käyttää strncpy:tä, koska se tarkistaa kopioitavan tekstin pituuden.


      • *BSD
        Mik26 kirjoitti:

        Kun tuolle annetaan yli 800 merkkiä, niin segfaultin saaminen on mitä todennäköisempää. Lue aina maksimissaan vain varatun muistialueen määrä merkkejä, ja muista varata tilaa vielä NULL-merkille.

        mainin strcpy on ihan turha, koska seuraavan rivin kutsu ylikirjoittaa x:n.

        Alemmassa funktiossa on myös kiinteä maksiarvo. Tuollaisen ylläpidettävyys menee vaikeaksi, jos jokaiseen uuteen paikkaan pitää muistaa aina laittaa joku arvo. Käytä #defineä tai mielummin varaa muisti dynaamisesti mallocilla. Dynaamisen muistin avulla voit palauttaa myös char * -tyyppisiä muuttujia (luonnollisesti se muisti pitää muistaa vapauttaakin free:llä).

        gets:n käyttöä kannattaa välttää, sillä se ei tarkista mahtuuko syötetty teksti sille annettuun muuttujaan vai ei.

        Samaten strcpy:n sijaan kannattaa käyttää strncpy:tä, koska se tarkistaa kopioitavan tekstin pituuden.

        > Samaten strcpy:n sijaan kannattaa käyttää
        > strncpy:tä, koska se tarkistaa kopioitavan tekstin
        > pituuden.

        Ja vielä kun käyttää strncpy():tä niin on tiedettävä, että strncpy() lisää '\0':n ton stringin perään vaan siinä tapauksessa, että kopioitava stringi on lyhyempi kuin parametriksi annettu koko!

        Tämän takia (size - 1) tai mahdollisesti strlcpy() ovat suositeltavia (tosin strlcpy() ei ole Posix 1003.1:n mukainen).


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

    Luetuimmat keskustelut

    1. SDP on vastuunkantaja, ja siksi suosituin kansan keskuudessa

      Kiusaamiseenkin SDP puuttuu heti sellaisen tultua ilmi. Esimerkiksi persut lakaisevat nämä maton alle ja pahentavat site
      Maailman menoa
      82
      6025
    2. Persut on Suomen mamutuspuolue nro 1.

      Heti ensimmäisenä persuvuonna 2015 maahantoivat Suomeen 35 tuhatta kunniavierastaan. Tuoreimpana persuvuonna 2025 pers
      Maailman menoa
      79
      4860
    3. Punavihreät puolueet haluavat Suomeen satoja tuhansia kehitysmaalaisia

      SDP, vihreät ja vassarit haluavat nostaa esim. pakolaiskiintiötä todella paljon. Orpon hallituksen aikana maahanmuutto
      Maailman menoa
      52
      4422
    4. SDP:n johto pesi kätensä häirintäkohusta

      "Suurimman oppositiopuolue SDP:n johto olisi todennäköisimmin halunnut vaieta puolueen ympärillä velloneen häirintäkohun
      Maailman menoa
      57
      4182
    5. SDP on selvästi paras valinta äänestyskopissa

      Puolueella on arvomaailma kohdallaan, sillä on hyvä CV itsenäisen Suomen historiassa vastuunkantajana ja hyvinvointivalt
      Maailman menoa
      96
      3789
    6. Miksei Korhonen (pers) vastaa Kokon (sd) esittämiin kysymyksiin?

      Hyviin käytöstapoihin kuuluu kysymyksiin vastaaminen, eikä alkaa syyttelemään kysymyksen esittäjää. Mikä vaivaa Korhost
      Maailman menoa
      6
      3512
    7. Häirintäkohun keskellä olevalta kansanedustajalta Jani Kokolta (sd) rajua tekstiä somessa.

      https://www.is.fi/politiikka/art-2000011772322.html Ajaakohan tämä SDP:n kansanedustaja Jani Kokko oikein täysillä valoi
      Maailman menoa
      89
      2554
    8. SDP:n selitykset ontuu pahasti - "On käsitelty heti, mutta kukaan ei tiedä"

      Kokoomuslaiset pistää taas demareita nippuun. Tuppuraisen mukaan mukaan SDP:n useat ahdistelutapaukset on käsitelty het
      Maailman menoa
      50
      2503
    9. Oletko nainen turhautunut, kun en tule juttelemaan siellä?

      Haluaisin tottakai tulla. Älä käsitä väärin. Ehkä ensi kerralla?
      Ikävä
      35
      2409
    10. Kähmijä puolueen kannatus romahtamassa

      Erityisesti naiset ovat suuttuneet SDP:lle kertoo asiantuntijat
      Maailman menoa
      47
      2139
    Aihe