christian1986 Skrevet 16. september 2005 Del Skrevet 16. september 2005 (endret) Jeg har laget et program for å løse 2. gradsligninger. Det jeg ønsker er at programmet skal fortsette å spørre etter et tall, om man taster inn en bokstav. Noen som vet hvordan dette lar seg gjør, er nybegynner på området Endret 21. oktober 2005 av christian1986 Lenke til kommentar
buskmann Skrevet 16. september 2005 Del Skrevet 16. september 2005 Header File stdlib.h Category Conversion Routines, Math Routines Prototype int atoi(const char *s); int _wtoi(const wchar_t *s); Description Converts a string to an integer. atoi converts a string pointed to by s to int; atoi recognizes (in the following order) An optional string of tabs and spaces An optional sign A string of digits The characters must match this generic format: [ws] [sn] [ddd] In this function, the first unrecognized character ends the conversion. There are no provisions for overflow in atoi (results are undefined). Return Value atoi returns the converted value of the input string. If the string cannot be converted to a number of the corresponding type (int), atoi returns 0. Lenke til kommentar
christian1986 Skrevet 16. september 2005 Forfatter Del Skrevet 16. september 2005 Men hvor skal dette legges inn? Spiller det ingen rolle hvor i programmet jeg plasserer det? Lenke til kommentar
christian1986 Skrevet 16. september 2005 Forfatter Del Skrevet 16. september 2005 Kom igjen da. Trenger svar.... Lenke til kommentar
buskmann Skrevet 16. september 2005 Del Skrevet 16. september 2005 do { cin >> inntall } while (atoi(inntall) == 0) Lenke til kommentar
Peter Skrevet 16. september 2005 Del Skrevet 16. september 2005 (endret) do {cin >> inntall } while (atoi(inntall) == 0) Blir det ikke: do { cin >> inntall; } while (atoi(inntall) != 0); ? Og hva skjer egentlig dersom brukeren skriver inn 0? Endret 16. september 2005 av Nazgul Lenke til kommentar
GenericName Skrevet 16. september 2005 Del Skrevet 16. september 2005 (endret) ... Endret 11. januar 2011 av Token Lenke til kommentar
Peter Skrevet 16. september 2005 Del Skrevet 16. september 2005 Jeg har != 0, mens buskmann har == 0 Lenke til kommentar
GenericName Skrevet 17. september 2005 Del Skrevet 17. september 2005 (endret) ... Endret 11. januar 2011 av Token Lenke til kommentar
Peter Skrevet 17. september 2005 Del Skrevet 17. september 2005 (endret) atoi returns the converted value of the input string. If the string cannot be converted to a number of the corresponding type (int), atoi returns 0. atoi("a") == 0 atoi("0") == ? Endret 17. september 2005 av Nazgul Lenke til kommentar
christian1986 Skrevet 21. oktober 2005 Forfatter Del Skrevet 21. oktober 2005 Er litt trist at så mange svarte meg, men ingen slik at jeg forstod det. Prøvde å følge oppskriftene, men det gikk ikke. Om noen gidder å gi meg en god beskrivelse hadde det vært flott ! Lenke til kommentar
dayslepr Skrevet 21. oktober 2005 Del Skrevet 21. oktober 2005 (endret) #include <iostream> using namespace std; template<typename T> void readStdin(T& t, std::string msg, std::string on_wrong_input) { std::cout << msg << std::flush; while(!(std::cin >> t)) { std::cout << on_wrong_input; std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::cout << msg << std::flush; } } // readStdin int main() { int tall; readStdin(tall, "tast inn et tall: ", "du tastet ikke inn et heltall, fors0k igjen!\n"); cout << "2 * " << tall << " = " << 2 * tall << endl; return 0; } tast inn et tall: u du tastet ikke inn et heltall, fors0k igjen! tast inn et tall: o du tastet ikke inn et heltall, fors0k igjen! tast inn et tall: x du tastet ikke inn et heltall, fors0k igjen! tast inn et tall: 3 2 * 3 = 6 edit: den skal håndtere andre typer på riktig måte også, f.eks. flytetall .. og også brukerdefinerte typer med operator>> definert for seg ....... edit2: tilsvarende i Common Lisp: (defun ensureRead (type) (do ((res (read) (read))) ((typep res type) res))) > (ensureRead 'number) u x 54523 =>54523 > Endret 21. oktober 2005 av dayslepr Lenke til kommentar
Mr.Garibaldi Skrevet 21. oktober 2005 Del Skrevet 21. oktober 2005 (endret) Kanskje dette er det du er på jakt etter int tall; char c lesTall: c = fgetc; if(!((c > 47) && (c < 58))) goto lesTall; tall = atoi(c); EDIT: Må bare si Coq Roque sin metode er mye bedre enn min, da jeg ikke tok høyde for at tallet kunne ha flere siffer. Jeg skylder på La Vieille Ferm Endret 21. oktober 2005 av Mr.Garibaldi Lenke til kommentar
Coq Rouge Skrevet 21. oktober 2005 Del Skrevet 21. oktober 2005 Problemet ditt kan løses på mange måter. Den enkleste er buskmann sin do { cin >> inntall; } while (atoi(inntall) == 0); Det denne koden gjør er å først lese inn en tekst til inntall (intall må være definert som et char array). Deretter sjekker den om det er et tall eller ikke med kallet atoi(inntall). Det dette kallet returnerer er tallet som ble funnet, evt 0 hvis inputten ikke ble gjenkjent som et tall (evt hvis tallet er 0). Alternative (og i mine øyne mye morsommere måten å gjøre det på) er å lage en egen variant av atoi. Det kan ganske kjapt gjøres slikt: char * inntall = new char[10]; int tall = 0; bool lovlig_input = false; // Så lenge du ikke har fått lovlig input, kjør en gang til while (! lovlig_input) { cout << "Skriv inn et tall: "; cin >> inntall; bool fortsett = true; for (int i = 0; i < 10 && fortsett; i++) { // Sjekk om symbolet er et tall mellom 0 og 9 (inklusivt) if (inntall[i] - '0' >= 0 && inntall[i] - '0' <= 9) { // Legg til gamle tallet (forsyv eksisterende med en titallsplass tall = tall * 10 + (inntall[i] - '0'); // Si at du har en lovlig input lovlig_input = true; } else { // Du har støtt på et tegn som ikke er tall, avslutt sjekkinga av strengen fortsett = false; } } } Coq Rouge (ikke testet koden, så vil ikke garantere for den, men prinsippet stemmer i det minste [tror jeg i alle fall ]) Lenke til kommentar
Mr.Garibaldi Skrevet 21. oktober 2005 Del Skrevet 21. oktober 2005 (endret) Siden det fortsatt er reklame på TvNorge.. Skrevet om til c og kuttet litt ned, men ellers likt. char inntall[10]; double tall = -1; int convert = 0, i, negativ = 0; printf("Skriv inn et tall:"); while (tall < 0) { fgets(inntall, 10, stdout); /* sjekker om tallet er negativt */ if(inntall[0] == '-') { negativt = 1; inntall[i] = 0; } for (i = 0; inntall[i]; i++) { /* Sjekk om symbolet er et tall eller om det . */ if ((isdigit(inntall[i]) || (inntall[i] == '.')) { convert = 1; } else { convert = 0; negativ = 0; } } if(convert) tall = atof(inntall); } if(negativ) tall *= -1; Heller ikke testet, men skulle funke.... EDIT: Endret så den nå tar høyde for negative tall og flyttall. Ikke helt elegant, men men... Endret 22. oktober 2005 av Mr.Garibaldi Lenke til kommentar
Coq Rouge Skrevet 21. oktober 2005 Del Skrevet 21. oktober 2005 Kanskje dette er det du er på jakt etter int tall; char c lesTall: c = fgetc; if(!((c > 47) && (c < 58))) goto lesTall; tall = atoi(c); EDIT: Må bare si Coq Roque sin metode er mye bedre enn min, da jeg ikke tok høyde for at tallet kunne ha flere siffer. Jeg skylder på La Vieille Ferm 5041088[/snapback] Takker for positiv tilbakemelding . Men vil påpeke et par små ting i koden din her. 1) Bruk av goto. Dette er generelt sett ansett som en dum ting å gjøre. I Wikipedia står det noe om dette, blandt annet om Dijkstra sine argumenter mot dette allerede i 1968 (og Dijkstra er en person det som regel lønner seg å høre på. Noen av argumentene mot goto er blandt annet det at det er umulig å bevise noe rundt koden (er kanskje ikke så veldig stort problem i dette tilfellet, men i store systemer så kan det fort bli det); det er også veldig mye vanskligere å lese goto, særlig da en ofte hopper i scope og ofte mange linjer med kode. 2)Bruken av de 'magiske' tallene 47 og 58 for '0' og '9'. Det er faktisk ikke alle tegnsett som har 0 og 9 på disse tallverdiene. Dessuten er det mye enklere å skjønne '0' og '9' i koden. Coq Rouge (Foretrekker 10 ekstra linjer med kode som er lett å lese enn 2 linjer som du bruker en dag på å skjønne) Lenke til kommentar
dayslepr Skrevet 21. oktober 2005 Del Skrevet 21. oktober 2005 (endret) Foretrekker 10 ekstra linjer med kode som er lett å lese enn 2 linjer som du bruker en dag på å skjønne koden min du sikter til? om du lurer på noe er det jo forsåvidt bare å spørre, det er ikke noe galt med koden (eller idéen) i det hele tatt; det er standard C++ .. det er i det minste gjort et forsøk på å gjøre den en smule mer fleksibel enn de andre eksemplene ... .. . forsøkt med flytetall, eller negative tall for den saks skyld? .. hva med komplekse tall? (std::complex?) her er den igjen, og litt mer fleksibel -- man kan bruke den mot andre streamer, f.eks. en netverksstream for kommunikasjon over Internet: #include <iostream> using namespace std; template<typename T> void readToType(T& t, string msg = "", string on_wrong_input = "", unsigned int tries = 10, istream& istr = cin, ostream& ostr = cout) { unsigned int i = 0; if(msg != "") ostr << msg << flush; while(!(istr >> t) && i < tries) { i++; if(on_wrong_input != "") ostr << on_wrong_input; istr.clear(); istr.ignore(numeric_limits<streamsize>::max(), '\n'); if(msg != "") ostr << msg << flush; } } // readToType template<typename T> class Point { public: T x, y; }; // Point template<typename T> ostream& operator<<(ostream& o, Point<T>& point) { o << point.x << ',' << point.y << endl; return o; } // operator<< template<typename T> istream& operator>>(istream& i, Point<T>& point) { i >> point.x; char comma; readToType(comma, "", "", 1, i, clog); i >> point.y; return i; } // operator>> int main() { double flytetall; readToType(flytetall, "tast inn et flytetall: ", "du tastet ikke inn et flytetall, fors0k igjen!\n"); cout << "kvadratet av " << flytetall << " er " << flytetall * flytetall << endl; Point<double> point; readToType(point, "tast inn et koordinat; to tall med komma i mellom, f.eks. `3.14, 100.2' : ", "feil format paa inntasting, fors0k igjen!\n"); cout << point; cout << "x er `" << point.x << "' y er `" << point.y << "'" << endl; return 0; } lars@blackbox ~/tests $ ./atast inn et flytetall: 100.2 kvadratet av 100.2 er 10040 tast inn et koordinat; to tall med komma i mellom, f.eks. `3.14, 100.2' : 3.14, 100.2 3.14,100.2 x er `3.14' y er `100.2' lars@blackbox ~/tests $ ./a tast inn et flytetall: 21 kvadratet av 21 er 441 tast inn et koordinat; to tall med komma i mellom, f.eks. `3.14, 100.2' : 3.14, 100.2 3.14,100.2 x er `3.14' y er `100.2' lars@blackbox ~/tests $ ./a tast inn et flytetall: -123 kvadratet av -123 er 15129 tast inn et koordinat; to tall med komma i mellom, f.eks. `3.14, 100.2' : -3.14, 100.65 -3.14,100.65 x er `-3.14' y er `100.65' lars@blackbox ~/tests $ ./a tast inn et flytetall: 32 kvadratet av 32 er 1024 tast inn et koordinat; to tall med komma i mellom, f.eks. `3.14, 100.2' : 3.14, 32 3.14,32 x er `3.14' y er `32' lars@blackbox ~/tests $ ./a tast inn et flytetall: 123 kvadratet av 123 er 15129 tast inn et koordinat; to tall med komma i mellom, f.eks. `3.14, 100.2' : 3.12 , 321.12 3.12,321.12 x er `3.12' y er `321.12' lars@blackbox ~/tests $ $ ./a tast inn et flytetall: 231 kvadratet av 231 er 53361 tast inn et koordinat; to tall med komma i mellom, f.eks. `3.14, 100.2' : blabla aoeu feil format paa inntasting, fors0k igjen! tast inn et koordinat; to tall med komma i mellom, f.eks. `3.14, 100.2' : 123 321 123,21 x er `123' y er `21' lars@blackbox ~/tests $ edit: formatering edit 2: if'ene for msg og on_wrong_input trengs vel strengt tatt ikke Endret 22. oktober 2005 av dayslepr Lenke til kommentar
Mr.Garibaldi Skrevet 21. oktober 2005 Del Skrevet 21. oktober 2005 (endret) Takker for positiv tilbakemelding . Men vil påpeke et par små ting i koden din her. For all del. Jeg hakket jo løs på din 1) Bruk av goto. Dette er generelt sett ansett som en dum ting å gjøre. I Wikipedia står det noe om dette, blandt annet om Dijkstra sine argumenter mot dette allerede i 1968 (og Dijkstra er en person det som regel lønner seg å høre på. Noen av argumentene mot goto er blandt annet det at det er umulig å bevise noe rundt koden (er kanskje ikke så veldig stort problem i dette tilfellet, men i store systemer så kan det fort bli det); det er også veldig mye vanskligere å lese goto, særlig da en ofte hopper i scope og ofte mange linjer med kode. Sant. Kunne like gjerne laget en while() løkke, men goto var det første som falt meg inn, samt at jeg nesten aldri ellers bruker det. Men siden du insisterer /* * en løkke som leser inn en char fra kommandolinjen * hvis den ikke er et tall, leser inn et nytt tegn. * hvis det er et tall avsluttes løkken og char c konverteres til en int */ int tall; char c do { c = fgetc(stdin); } while ((c > 47) && (c < 58)); tall = atoi(c); 2)Bruken av de 'magiske' tallene 47 og 58 for '0' og '9'. Det er faktisk ikke alle tegnsett som har 0 og 9 på disse tallverdiene. Dessuten er det mye enklere å skjønne '0' og '9' i koden. Tja... Så vidt meg bekjent er de første 128 tegnene like for ASCII, UTF-8/16/32 samt ISO 8859 og windows tegnsettet, noe som skulle dekke de fleste tegnsettene i bruk i dag. Coq Rouge (Foretrekker 10 ekstra linjer med kode som er lett å lese enn 2 linjer som du bruker en dag på å skjønne) 5041305[/snapback] Touché! Skal huske å kommentere bedre neste gang... dayslepr> Godt poeng med versatiliteten, men siden han kun var på jakt etter en metode for bruk til utregning av en andregradsligning, så er det noe begrenset hva som trengs. (Men flyt-tall og negative tall er jo noe som vi også burde tatt høyde for) EDIT: Som det nå er tatt høyde for i min omskrivning av Coq Rouges kode Endret 22. oktober 2005 av Mr.Garibaldi Lenke til kommentar
dayslepr Skrevet 21. oktober 2005 Del Skrevet 21. oktober 2005 Mr.Garibaldi: bare jeg som er trøtt, grinete og paranoid ..... Lenke til kommentar
Peter Skrevet 21. oktober 2005 Del Skrevet 21. oktober 2005 Mr.Garibaldi: bare jeg som er trøtt, grinete og paranoid ..... 5041737[/snapback] Og på et ganske mye høyere nivå enn de fleste andre av oss her... (Har ikke sett deg her på år og dag nå, hyggelig at du tok turen tilbake) Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå