Het wegwerken van strings in het databestand

Ik heb een code geschreven die een vierkante matrix leest uit een .dat-bestand en een vector uit een apart .dat-bestand en vergroot de twee en voert gauss jordan eliminatie uit om de augmented matrix in row-reduced-echelon-vorm te krijgen. Ik probeer het nu gebruiksvriendelijk te maken en elegant te crashen wanneer de gebruikersinvoer onzinnig is. Ik heb bijvoorbeeld een controle om te controleren of de matrix vierkant is en of de lengte van de vector overeenkomt met de dimensie van de matrix. Wat ik nu probeer te doen, is controleren of er tekens of symbolen in de gegevensbestanden zitten die geen nummers zijn.

Mijn poging: zoiets als scanf ("% lf",) zou werken omdat het stopt wanneer het een van deze symbolen tegenkomt. Het probleem is dat mijn invoer niet van de opdrachtregel is. (de opdrachtregel is hier niet echt een optie omdat ik wil dat de code een enorme matrix kan accepteren die de gebruiker niet zou willen zitten om de opdrachtregel in te voeren). Doom fscanf ("% f",) wordt gek als het een string tegenkomt. Is er zoiets als scanf dat gewoon stopt maar niet gek wordt als het een brief tegenkomt, enzovoort? Zo niet, zijn er nog andere suggesties?

1
Laat het niet crashen! Elk normaal programma voert een foutcontrole uit en stopt met een foutmelding als het niet goed werkt. Wat betreft uw vraag, het is waarschijnlijk het schoonst om parsen, validatie en verwerking te scheiden, en u kunt dus gewoon stoppen als er een parseer- of validatiefout is.
toegevoegd de auteur Kerrek SB, de bron
+1 voor " ... crash elegant ... " :-) Hoe serieus ik ook ben, ik ben het volledig eens met wat Kerrek SB hierboven schreef! Bovendien zou ik scanf() retourneren EOF willen vermelden nadat " gek was geworden ", dus je zou gemakkelijk deze voorwaarde kunnen opvangen tijdens runtime.
toegevoegd de auteur alk, de bron
lees alles als string, test validiteit en converteer ...
toegevoegd de auteur Mitch Wheat, de bron

1 antwoord

Gebruik fgets om een ​​regel in een vooraf toegewezen buffer te krijgen, en vervolgens strtoX om een ​​drijvende-kommawaarde te extraheren. ( X = f voor float , X = d voor dubbel , X = ld voor lang dubbel . De handtekening is X_t strtoX (const char * nptr, char ** endptr) , waarbij X_t het overeenkomende type is ( float , dubbel , of lang dubbel ).

Tot het einde van de regel is bereikt ( ** endptr = '\ n' ), verhoogt u de regelaanwijzer (die is ingesteld om naar de vooraf toegewezen buffer te wijzen en als deze niet wordt verhoogd na strtoX , verhoog het dan totdat het is. Gebruik twee variabelen, zoals:

char *lp = buf;
char *lp2 = buf;
do {
    X_t x = strtoX(lp, &lp2);
    if (lp == lp2 && *lp != '\n') {
        ++lp;
        continue;
     }
     if (*lp2 == '\n')
         goto read_line;
     //do something with x
 } while (1);

Mijn code is niet geweldig, maar het moet het nut laten zien.

strtoX voor X = f en X = ld wordt niet ondersteund tot C99/POSIX 2011.

1
toegevoegd