Ongelmana on kahden merkkijonona annetun ajan erotuksen laskeminen. Voisin muuttaa tuloksen sekunneiksi ja laskea siitä mutta se tuntuu jotenkin kömpelöltä tavalta ja löysin Ctime kirjastosta valmiin funktion mikä laskee ko. asian.
int Aikaero(const char aika1[9], const char aika2[9], char ero[9]) { tm time1; tm time2; time_t erotus = 0; time_t luku1 = 0; time_t luku2 = 0; tm *time3; tm time4; tm *pointteri1 = &time1; tm *pointteri2 = &time2; sscanf (aika1, "%2i:%2i:%2i", &time1.tm_hour, &time1.tm_min, &time1.tm_sec); sscanf (aika2, "%2i:%2i:%2i", &time2.tm_hour, &time2.tm_min, &time2.tm_sec); cout << time1.tm_hour << " tuntia " << time1.tm_min << " minuuttua ja " << time1.tm_sec << " sekuntia." << endl; cout << time2.tm_hour << " tuntia " << time2.tm_min << " minuuttua ja " << time2.tm_sec << " sekuntia." << endl; luku1 = mktime (pointteri1); luku2 = mktime (pointteri2); cout << "luku1: " << luku1 << " ja luku2: " << luku2 << endl; erotus = difftime(luku1, luku2); cout << "erotus on " << erotus << endl; time3 = localtime (&erotus); cout << "Saatu arvo on " << asctime(time3) << endl; //time4 = time3; sprintf(ero, "%2i:%2i:%2i", time4.tm_hour, time4.tm_min, time4.tm_sec); return 0; }
Ongelmana on arvon sijoittaminen muuttujiin luku1 ja luku2. Ne saavat arvon -1 eli eivät toimi. Time1 ja Time2 tietueet saavat arvot oikein haettua aika1 ja aika2 merkkijonoista. Sen jälkeisestä koodista ei ole varmuutta vielä toimiiko se (ei ainakaan valita virheistä) kun koodi "kosahtaa" jo tuossa paikkeilla. Joku jolla enemmän kokemusta CTime kirjastosta voisi antaa muutaman pointterin missä mättää ni projekti jatkuisi jouhevasti.
Täytä time1:n ja time2:n kaikki kentät, tai siis laita niihin edes jotakin. Nyt niissä voi olla mitä tahansa. http://www.opengroup.org/onlinepubs/009695399/
Kokeilin lisätä alkuun
tm time1 = {{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}};
mutta tämä ei auttanut. Käyttäjältä kysytään vain kahdet tunnit, minuutit ja sekunnit joiden erotus tulisi laskea.
Jos olisit katsonut tuon linkin, niin tietäisit, ettei aivan mikä tahansa arvo käy. Esimerkiksi päivän pitää olla väliltä {1, 31}. Jos vaikka ahkisit niihin molempiin aluksi senhetkisen ajan, niin voisit päästä vähimmällä.
Jep, pistin molempiin tämän hetkisen ajan ja paljastui että ongelma seuraava kompastuskivi on localtime joka ei vaikuta tekevän mitään. Tulostaa että "saatu arvo on Thu Jan 01 12:00:00 1970 eli ei sijoita arvoa mihinkään.
Edit: Sain jotenkuten toimimaan ja tarvitsisin apua muokkaamaan tiedot hh:mm:ss muotoon. Tuossa olevalla sprintf:llä se onnisuu jos arvot saisi sijoittumaan jonnekkin oikeaan paikkaan eikä pointterin varaan.
Mikä tuossa tietojen asettelussa siis on ongelmana?
Teinpä nyt tästä sen toimivan (?) version tännekin näytille.
char * Aikaero(const char alku[9], const char loppu[9], char ero[9]) { // Muut nollia paitsi nämä: // kuukauden päivä: 1 // vuosi: 1900 + 100 = 2000 // viikonpäivä: 6 (lauantai) tm time1 = {0,0,0,1,0,100,6,0,0}; tm time2 = time1; time_t erotus; // Luetaan ajat sscanf (alku, "%2i:%2i:%2i", &time1.tm_hour, &time1.tm_min, &time1.tm_sec); sscanf (loppu, "%2i:%2i:%2i", &time2.tm_hour, &time2.tm_min, &time2.tm_sec); // Erotus erotus = (time_t) difftime(mktime(&time2), mktime(&time1)); // Otetaan se positiivinen versio, muuten bugaa if (erotus < 0) erotus = -erotus; // Muunnetaan ja kopioidaan aika muuttujaan time1 // HUOM: localtime lisää siihen aikavyöhykkeen, älä käytä sitä! time1 = *(gmtime(&erotus)); // Huom nollat sprintf:ssä, ettei tule "2: 9: 3" vaan "2:09:03" sprintf(ero, "%2i:%02i:%02i", time1.tm_hour, time1.tm_min, time1.tm_sec); // Tämä on aina kiva. Nyt voi laittaa näin: // cout << Aikaero(aika1, aika2, ero) << endl; return ero; } int main(int argc, char *argv[]) { char ero[9]; cout << Aikaero("13:20:00", "12:30:01", ero) << endl; return 0; }
Zmyrgel kiittää ja kumartaa.
Lähinnä se vika oli tuossa localtimessä mikä sekoitti sitten sprinf:n kokonaan kaataen ohjelman.
Nyt kun kriittiset osat kunnossa voi käydä kikkailemaan tähän jotain hienouksia :)
Löyty ihan uusia juttujakin tuosta mallista kuten tuo positiivisen version ottaminen ja nollat sprintf:ssä, ei ole tullut mieleen että noinkin voi asiat tehdä. Mutta takaisin suunnittelupöydän ääreen miettimään mistä aiheesta generoi seuraavan ongelman :)
Sellaista vielä että tuo "ero" pitäisi saada palautettua muuttujaparametrinä tuonne pääohjelmaan ja en saa sitä oikein aikaiseksi.
Koska kyseessä on taulukko niin se ei voi olla viittausparametri joten sen pitää olla osoitinparametri eikö? Eli funktion esittelyyn ja itse funktion alkuun laitetaan char *ero[9] eikö?
Tähän saakka olen päässyt mutta tämän jälkeen tulee ongelmat miten sijoittaa arvo siihen. Olen kokeillut laittaa suoraan sprintf:llä mutta joko herjaa taikka sitten kaatuu siihen. Sprintf:llä laittanut arvon väliaikaiseen muuttujaan ja memcpy:llä kokeillut kopioida arvoa oikeaan paikkaan mutta mikään ei tunnu toimivan.
Niinhän tuo esimerkki juuri toimii, ainakin GCC:llä käännettynä. Katso vaikka cout << ero;
Jos ei, niin laita parametrin muodoksi "char *ero", niin sille kelpaa mikä tahansa char-taulukko, ja arvot muuttuvat. Näin yleensä näkee tehtävän.
"char * ero[9]" tarkoittaa, että taulussa "ero" on yhdeksän "char *" -tyyppistä kohtaa.
Joo, no sen pitää palauttaa se integer arvo että tuo erotus. Sain pienen kokeilun jälkeen toimimaan, oli väärä muuttujan määrittely (char *ero[9]). Mutta nyt näyttäisi pelittävän oikein hyvin.
Kiitos vaan paljon avusta.
Aihe on jo aika vanha, joten et voi enää vastata siihen.