Lad os antage at tallene er integers, en mulighed er at bruge scanf :
int a, b, c, d; int antalMatched;
antalMatched = sscanf( modtagetTekst, "%d * %d * %d * %d ", &a, &b, &c, &d ) if( antalMatched != 4 ) { // Det gik ikke godt - fejlbehandling } else { // Vi fik fundet alle fire værdier }
Scanf returnerer antallet af variable der har fået tildelt en værdi under scanningen - derfor checker jeg i koden om returværdien er netop 4 - hvis den er det har de fire variable a, b, c og d fået de ønskede værdier.
arne_v-> jeg ved det virker til det projekt han laver, for jeg laver præcis det samme i øjeblikket. Det er et fast antal int der bliver sendt i den streng fra cykelcomputeren, så det virker fint nok... Men du må da gerne vise en løsning der kan håndtere vilkårligt antal felter, for det kan både tagryggen og jeg bruge! :)
For at håndtere et vilkårligt antal felter, så kig på strtok eller strchr.
Muffet, som Arne skriver, så er hsloths løsning mere generel (og derfor IMO bedre). Men hvis du insisterer på at lave det med strncpy, så brug i det mindste nogle konstanter i stedet for hårdkodede værdier.
olennert - > nårh ja... men jeg har kun været i gang lidt længere end et halvt år... men jeg tager kritikken til mig, og det ender jo nok også med at jeg retter min egen kode :)
arne_v - > ja, gearet er i intervallet 0-9, det er en kondicykel, ikke en alm. cykel med udvendige gear, for der har min i hvert fald 27, så det er jeg da godt klar over :)
Så kan i jo lige tænke lidt over hvorfor det her program (frit efter hslot) giver "forkerte" retur væredier. Simple løsning: Afgrænds løsninger til kun at tage forbehold for at tallene kun må være mindre end den mindst tilladte MAX_INT. Lidt mere kompliceret brug strtol og enten strtok eller mere som muffet's løsning, men da i bruger C skulle i nok kikke på noget med << istedet.
#include <stdlib.h> #include <stdio.h>
void Beregn(char const *modtagetTekst) { int a, b, c, d; int antalMatched;
if( antalMatched != 4 ) { // Det gik ikke godt - fejlbehandling printf("ups - '%s' gik ikke godt\n", modtagetTekst); } else { // Vi fik fundet alle fire værdier printf("ok - '%s' gav %d %d %d %d\n", modtagetTekst, a, b, c ,d); } }
int main() { Beregn("12345678901*1*12*123"); Beregn("66000*1*12*123"); Beregn("1*23*456*7890");
return EXIT_SUCCESS; }
Y:\TEST>sscanf ok - '12345678901*1*12*123#' gav -1 1 12 123 ok - '66000*1*12*123#' gav 464 1 12 123 ok - '1*23*456*7890#' gav 1 23 456 7890
Du kan godt lave sscanf-løsningen ligeså robust som strtol-løsningen. Hvis du #include <inttypes.h> så defineres scanf-flag som SCNu64, og typer som uint64_t. Forudsat oversætteren altså har en 64-bit heltalstype. I øvrigt vil der så også gælde at hvis oversætteren *ikke* har en 64-bit heltalstype, så får du det samme problem med strtol, idet long så vil være 32-bit.
Fordelen ved strtol er at du kan få en fejlmelding, at den er i errno er selvfølgelig stadig et problem.
Den første giver fejl fordi 12345678901 ikke kan være i en long på min compiler, dette ville bliver fanget da errno ville blive sat til ERANGE.
Den anden giver fejl fordi jeg har oversat den på en 16-bit maskine og 66000 ikke kan være i en 16-bit int, dette burde give en fejl da den konverteres til int (66000-65536=464), nu husker jeg ikke lige hvad der bliver kaldt i C , men i C mener jeg at sscanf med et '%d' kalder atoi som virkelig er (int)strtol(s, (char **)NULL, 10).
segmose -> Du har fuldstændig ret. Men med 64-bit heltal uden fortegn er maksimumværdien 18,446,744,073,709,551,615 hvilket er et forholdsvist stort tal. Hvis dine inddata er garanteret at holde sig mellem 0 og 2^64 - 1, så kan du bruge sscanf med SCNu64 og uint64_t. Hvis ikke, så kan du bruge strtoul, og checke mod ERANGE (og i øvrigt håbe på at en long er 64 bit på den platform).
Fordelen ved uint64_t er at det sædvanligvis er en flytbar indpakning af eksempelvis long long, eller andre oversætterafhængige tingester.
Så med uint64_t og SCNu64 kan du indlæse store tal uden range check, med long kan du måske kun læse 32-bit tal, men med range check. YMMV.
Forenklet går det ud på at de data typer som man vælger skal kunne indeholde de værdier som i forsøger at indlæse, det nytter ikke at ville læse 66000 ind i en 16 bit int type. (læs i din include/limits.h hvilke værdier der på denne compiler på denne maskine der er tillad for hvilke typer).
Så diskuterer vi den sikreste måde at indlæse på, enten tager man forbehold for at de data man vil indlæse er i den formoede værdi område eller man sikre sig både i den ene ende og den anden.
muffet's er den mest usikre metode, den virker kun hvis data er lige præcis som han formoder, der checkes ikke for fejl værdier og position af adskillelser.
hsloth's er ok hvis værdierne holder sig inden for 'int' området, hvilket sikkert er tilfældet her.
olennert foreslår at man benytter nogen af de nye type der er defineret i nyeste C standard som forøger værdi området enormt.
Jeg er bare lidt paranoid over ting man modtager fra andre enheder (cyclecomputer->PC) Er transmission ufejlbarlig? fanger man fejl i transmissionen så hvis der pludselig står "3x7*" istedet for "347*" at det bliver til en fejl, hvad det gør i hsloth's men ikke i muffet's. Sender alle modeller nøjagtig ens? har felterne fast bredde uanset værdi? hvis en af felterne bliver længere eller korterer alt efter værdien fejler muffet's også.
tagryggen -> Undskyld, det er let at blive revet med. Det er et emne der interesserer mig (og formentlig også interesserer segmose, ellers ville han nok ikke bruge tid på dette her). Og så kan man godt komme til at glemme målgruppen.
Men det er altid en god ide at tænke lidt over hvordan ens inddata ser ud, og hvordan ens kode kommer til at håndtere fejlsituationer. Det er fint nok (i kode der ikke skal køre i rigtig produktion; det virker lidt som om det her handler om en opgave på en eller anden uddannelsesinstitution) at antage at ens inddata altid er perfekte, men så husk lige at dokumentere den antagelse.
Så læs lige segmoses opsummering af diskussionen. Tankerne omkring hvor store heltal egentlig kan blive er ganske interessante. Og det bliver rigtigt spændende når vi kommer over i flydende tal :-).
Men sommetider er det en god ting at bemærke, hvis en feature er knyttet til en nyere standard.
inttypes.h er fra en X/Open standard og er selvom standarden ikke er ny ikke med i alle C compilere.
limits.h er med i ANSI C standarden og bør være i alle compilere idag.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.