getline() wird vom compiler nicht erkannt
-
while (nRet = getline(zeile, t, datei)) > 0) { ptr = strtok(*zeile, ","); while (ptr != NULL) { c = atoi(ptr); add(&c); } ausgabe(); loesche_alles(); } return EXIT_SUCCESS;
beim versuch das (und denn restl. code) zu kompilieren erhalte ich die Fehlermeldung:
"'getline' undeclared <first use this function>"
dabei habe ich diese funktion doch aus dem online buch "c von a bis z"
(http://www.pronix.de/pronix-793.html)keine ahnung was ich tun soll, ich kenn auch keine andere funnktion die mir eine Zeile einliest die unbegrenzt lang sein kann...
Brauche dringend Hilfe, da ich C neuling bin, ist mein erstes programm.Vielen Dank
-
'getline' ist keine von den standard funktionen, wird wohl was selbstgebasteltes oder unix-krempel sein. zum einlesen von ganzen zeilen könntest du 'gets' oder 'fgets' nehmen.
btw: sei vorsichtig mit 'c von a bis z'. da steht viel mist drin.
-
ja ich merke schon, dass da viel mist drin steht.
ist die zeilenlänge bei fgets nicht durch eine maximale anzahl an zeichen beschränkt?
wenn ja, kann ich das nicht irgendwie variabel lassen?
-
jay186 schrieb:
ist die zeilenlänge bei fgets nicht durch eine maximale anzahl an zeichen beschränkt?
wenn ja, kann ich das nicht irgendwie variabel lassen?das ist ja das gute an 'fgets', dass man damit keine buffer overflows bekommt. was meinst du mit 'variabel'? wie viele zeichen kommen werden, kann man nicht vorhersehen. nimm einfach einen ausreichend grossen buffer.
-
Undertaker schrieb:
jay186 schrieb:
ist die zeilenlänge bei fgets nicht durch eine maximale anzahl an zeichen beschränkt?
wenn ja, kann ich das nicht irgendwie variabel lassen?das ist ja das gute an 'fgets', dass man damit keine buffer overflows bekommt. was meinst du mit 'variabel'? wie viele zeichen kommen werden, kann man nicht vorhersehen. nimm einfach einen ausreichend grossen buffer.
Mit Variabel meint er das Verhalten, welches getline() liefert.
@ jay186:
Die ANSI-C konforme Alternative zu getline wäre, das Ding selbst nachzubauen. Wenn du dich schon mit malloc()/realloc() auskennst, wäre das eine gute Übung.
Aber in der Regel reicht fgets() mit einem fixen Buffer für Usereingaben. War die Eingabe zu lang, dann wird einfach nochmal nach der Eingabe gefragtEdit: Und wenn ich mir den Beispielcode zu getline() anschaue komme ich zu dem Schluss, dass manche Menschen einfach keine Bücher schreiben sollten.
-
ok, es bleibt mir also nur de möglichkeit z.b. eine maximale länge von z.b.
1000000000000000000000000000000000
zu wählen?das problem ist, dass ich eine aufgabe lösen muss und da wird folgendes verlangt:
es muss auch mit sehr langen (beliebig langen) eingabezeilen umgehen können.
was soll ich da tun, anscheinend gibts so ein befehl nicht...
-
um getline() nachzubauen müsste ich also folgendes tun:
- mit fgets bestimmte anzahl zeichen in puffer-array einlesen
- testen, ob das die ganze zeile war (WIE??)
- falls nicht mit realloc puffer vergrößern (UM WIEVIEL??)
ich wär euch echt dankbar falls das jemand grob umreißen könnte wie das gehen soll, also die befehle. ein array mit malloc/realloc anpassen würd ich selber hinbekommen.
-
jay186 schrieb:
um getline() nachzubauen müsste ich also folgendes tun:
- mit fgets bestimmte anzahl zeichen in puffer-array einlesen
Ich würde der Einfachheit halber immer nur ein Zeichen einlesen (fgetc()) und nicht fgets dazu bemühen.
jay186 schrieb:
- testen, ob das die ganze zeile war (WIE??)
Genau so wie es fgets oder getline machen. Wenn ein newline '\n' kommt.
jay186 schrieb:
- falls nicht mit realloc puffer vergrößern (UM WIEVIEL??)
Den Speicher immer verdoppeln ist die gängige Strategie.
-
Vielen Dank, sehr hilfreich!
werd es mal probieren, also zeichen solange einlesen bis \n kommt und notfalls puffer-array vergrößern.
Nur noch eine allerletzte frage für heute:
wie prüfe ich, ob das array voll ist?
mir fällt da nur die möglichkeit ein einen counter mitzählen zu lassen und immer zu vergleichen, ob länge des arrays erreicht ist, wisst ihr was besseres?Vielen Dank nochmals!
-
jay186 schrieb:
wie prüfe ich, ob das array voll ist?
mir fällt da nur die möglichkeit ein einen counter mitzählen zu lassen und immer zu vergleichen, ob länge des arrays erreicht ist, wisst ihr was besseres?Was besseres wird dir bei "arrays" via malloc()/realloc() auch nicht einfallen.
PS: "arrays" in Hochkomma, weil man in C zwischen echten arrays und Zeigern auf Speicher (via malloc() etc) unterscheiden muss. Link: http://c-faq.com/aryptr/aryptr2.html (und folgende)
-
Gut, Danke.
Falls ich das nicht hinkriegen sollte, weiß ich ja wo ich Hilfe bekomme.
Vielen Dank nochmals!
(man kann sich nicht oft genug für freiwillige hilfe bedanken)
-
18.16.3 <- Das tut weh.
-
ich hab' das hier in meiner 'grabbelkiste' gefunden:
char *readline (void) { char *s, *p = 0; int c, n = 0; for (;;) { if (n%512 == 0) { p = realloc (p, n+512); s = p; } c = getchar(); if (c == '\n') { s[n] = 0; break; } s[n++] = c; } return p; }
sieht so aus, wie das, was du brauchst.
(fehlertest beim realloc fehlt)
-
Hey Danke für den code!
Folgende Fragen hätte ich trotzdem:
1. Warum ist im schleifenkopf der for schleife nichts drin?
2. Warum brauche ich 2 pointer s und p?
3. Warum wird n%512==0 üperprüft, woher kommen die 512?
4. c ist ein int wert, warum kommen da char's rein? (ich muss zahlen von einer datei einlesen, d.h. ich müsste mit atoi() und strtok() den string noch in zahlen umwandeln, aber jetzt wird in ein char array int-werte gespeicehrt, warum?
-
5. wenn n größer als 512 wird, dann wird kein neuer speicher mehr alloziert, da n%512 dann ungleich 0 ist und irgendwann wenn n bei 1025 ist wird das "array" überschritten, oder nicht?
-
jay186 schrieb:
1. Warum ist im schleifenkopf der for schleife nichts drin?
Weil es so praktischer ist.
Die Schleife läuft so lange bis '\n' eingegeben wird. Das in den Kopf zu packen würde die komplexität des Codes ein bisschen erhöhen. Deshalb nimmt er einfach eine "endlosschleife" und baut an der richtigen Stelle ein "break" ein um die Schleife zu beenden.
2. Warum brauche ich 2 pointer s und p?
In dem Code nicht. Erst wenn du einen Fehler bei realloc abfangen willst brauchst du 2 Zeiger. Den realloc würde dir s mit 0 überschreiben wenn es fehlschlägt und dein Speicher wäre weg.
3. Warum wird n%512==0 üperprüft, woher kommen die 512?
Frei erfunden. Es werden gerne 2er Potenzen genommen für Blockgrößen. Der Speicher in dieser Funktion wächst immer um 512 Bytes. Eine uU sinnvollere Strategie wäre ein *2 jedesmal. Im Prinzip ist die Zahl hier aber nur ein Schätzwert.
4. c ist ein int wert, warum kommen da char's rein? (ich muss zahlen von einer datei einlesen, d.h. ich müsste mit atoi() und strtok() den string noch in zahlen umwandeln, aber jetzt wird in ein char array int-werte gespeicehrt, warum?
Fehler im Code. EOF zeigt an wenn die Datei (oder in diesem Fall die Eingabe) zuende ist. zB wenn man eine Datei an das Programm piped. EOF kann aber kein char sein weil es nicht darstellbar ist. Deshalb ist EOF ein int und c muss daher ein int sein wenn man auf EOF testen will. Dieser Test fehlt im Code.
5. wenn n größer als 512 wird, dann wird kein neuer speicher mehr alloziert, da n%512 dann ungleich 0 ist und irgendwann wenn n bei 1025 ist wird das "array" überschritten, oder nicht?
n%512 ist 0 wenn n 0, 512, 1024,... ist. Jedesmal wenn das eintritt, wird das Array um 512 Elemente vergrößert.
% liefert ja den Rest einer Division. Und alle vielfachen von 512 sind restlos durch 512 teilbar.
Es fehlt in dem Code ein n+=512.
-
das hab ich mir mal überlegt:
char *puffer = NULL; unsigned int counter = 0; size_t t = 1000; puffer = calloc(t, sizeof(char)); while (true) { if (c = fgetc(FILE)) == "/n") break; else if (counter > "letzter Index des Arrays"){ t=2*t; puffer = realloc(puffer,t); puffer[counter++] = c;} else puffer[counter++] = c; }
-
danke nochmals für die erläuterungen, werde wohl den vorgeschlagenen code nehmen!
Noch ne Frage:
was passiert wenn die letzte Zeile kein newline hat? was kann man da tun?
-
Es heisst '\n' und nicht "/n" und du hast EOF vergessen. Weiters hast du keine Fehlerüberprüfung wenn realloc/calloc fehlschlagen.
EOF ist auch die Lösung des Problems wenn es kein \n gibt. fgetc liefert dir in so einem Fall EOF wenn er das Zeichen nach dem letzten liest.
-
okay danke! denke dass ich es jetzt hinbekommen.
noch eine frage:
was steht am Ende im "array"? integerwerte oder stringfolge?
kann ich also strtok() auf das "array" anwenden?