PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Dateiinhalt richtig parsen [C]



ichunddu
09-11-2006, 15:42
Hallöchen!
Ich möchte gerne wissen wie ich einen Dateiinhalt richtig parse?!

Ich hab da mal was mitgebracht ;)


memset(buffer, 0, sizeof(buffer));
ret = fread(buffer, sizeof(buffer)-1, 1, fp);
fclose(fp);

oldptr = ptr = buffer;
i = 0;
while( ptr < (buffer + strlen(buffer))) {
ptr = strchr(oldptr, '@');
if( ptr == NULL )
break;

strncpy(feld[i].variable, oldptr,
(((ptr-oldptr)) < sizeof(feld[i].variable) ?
((ptr-oldptr)) : sizeof(feld[i].variable)-1));
ptr++;
feld[i].variable2 = atoi(ptr);

while( *ptr != '\n' )
ptr++;
ptr++; // next line in buffer
oldptr = ptr;
i++;
if( i > 9 || ptr > (buffer + strlen(buffer) ) )
break;
}

Was soll der code machen?
In einer Datei stehen einige Werte. Diese soll so aussehen

String@Zahl
String@Zahl
String@Zahl
...
Eingelesen werden soll maximal 10 dieser Zeilen.
Dieser Code läuft auch wunderbar, nur wenn ich bspw. genau 10 Zeilen habe und in der letzten das Newline weglasse, kommt es zu einem Pufferüberlauf. Leider weiß ich nicht, wie ich den verhindern soll!
Die Stelle mit dem atoi() gefällt mir eigentlich auch nicht, aber hier ist es der Funktion anscheinend egal ob am Ende ein Newline steht oder nicht :)

Beatkiller
09-11-2006, 18:33
Dieser Code is echt heavy... Für so ne simple sache wie Zeilen aus ner Datei lesen gibst du dir echt viel Mühe, den Code aufzublasen. Muss das unbedingt mit fread() sein? Warum kein fgets? Das liest eh immer bis zum Ende der Zeile in einen Buffer.

Den Buffer selbst kannst du mit strtok parsen.

locus vivendi
09-11-2006, 20:31
Dieser Code läuft auch wunderbar, nur wenn ich bspw. genau 10 Zeilen habe und in der letzten das Newline weglasse, kommt es zu einem Pufferüberlauf. Leider weiß ich nicht, wie ich den verhindern soll!
Indem du C++, Iostreams, std::string, std::vector und ggf. auch Boosts lexical_cast verwendest. Damit hast du in maximal 15 Zeilen eine solide Implementierung.

Für das simple Dateiformat ist die Code-Ersparnis damit zwar noch nicht so dramatisch, aber solltest du jemals z. B. ein anderes Zeichen als Newline als Record-Separator nehmen wollen, und z. B. Strings mit Escape-Zeichen oder ähnliches, und nicht immer fest 10 Zeilen zum einlesen, dann wirst du ohne die obigen Mittel nicht viel Freude haben...

jeebee
10-11-2006, 17:03
ach und strtok sollte nicht verwendet werden (ich tus zwar auch), denn die man-page sagt dazu
Avoid using these functions. If you do use them, note that:

These functions modify their first argument.

These functions cannot be used on constant strings.

The identity of the delimiting character is lost.

The strtok() function uses a static buffer while parsing, so
it’s not thread safe. Use strtok_r() if this matters to you.