PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C | fgets wird einfach übersprungen ?!



Sector1379
20-12-2005, 18:00
Hallo zusammen

Ich habe ein sehr komisches Problem, wenn ich bei mir folgenden Code z.b versuche auszuführen wird fgets() einfach übersprungen.



printf("Bitte geben sie einen Satz ein");
fgets(satz, sizeof satz, stdin);


Wisst iht woran das liegen könnte, also die Anwendung der Funktion so wie ich es mache sollte Richtig sein.

Genau das selbe passiert auch bei der funktion gets().

Also ich finde das schon sehr komisch. :rolleyes:

Gruß Sector

edit: Ich hatte vergessen zu erwähnen, das ich unter Linux Programmire falls das wichtig ist

peschmae
20-12-2005, 18:51
Also bei mir funktionieren die Funktionen wie sie sollen. Hast du ein funktionierendes Minimalbeispiel?

MfG Peschmä

Caveman
20-12-2005, 19:20
(Ohne lange nachzudenken, würde ich sagen, dass es statt stdin STDIN_FILENO heißen muss.)

satz ist hoffentlich ein Puffer in dem etwas drin steht.

Edit:
Der Fehler muss im Puffer liegen.
Wenn er leer ist, ist die größe gleich null und wenn was drin steht, dann kannst Du genau soviele Zeichen einlesen, wieviel vorher drin waren.



#define BUFFERSIZE 80

satz[BUFFERSIZE];

fgets(satz,BUFFERSIZE,stdin);

So sollte es gehen.

Sector1379
20-12-2005, 20:29
So ich habe jetzt auch deinen Rat befolgt Caveman und habe per define ein Buffersize fetsgelegt. Leider auch wieder ohne Erfolg. Hier mal ein ausschnitt von dem Programm was ich schreiben wollte.



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

# define BUFFERSIZE 60


int descFile(void){



char progname[BUFFERSIZE];
char satz[BUFFERSIZE];
char author[BUFFERSIZE];




printf("*** Please answer the questions ***");

printf("*Programm Name: ");
fgets(progname,BUFFERSIZE,stdin);

printf("*Author Name: ");
fgets(author,BUFFERSIZE,stdin);

printf("*Please make a short description (q for exit):");
fgets(satz, BUFFERSIZE, stdin);
}

Also jetzt mal ehrlich ich seh da einfach keinen Fehler auch laut compiler ist alles Ok aber die Funktionen werden übersprungen.

Gruß Sector

Caveman
20-12-2005, 20:55
In all Deinen printf-Anweisungen fehlt am Schluss das Endezeichen "\n".

Sector1379
20-12-2005, 21:06
In all Deinen printf-Anweisungen fehlt am Schluss das Endezeichen "\n".

:) Ja richtig das weiß ich auch , das habe ich auch verzweiflung gemacht weil ich gesehen habe das nach dem Aufruf von fgets() satz[0] ein \n zugewiesen bekommt. Ich habe gedacht vielleicht geht es deshalb nicht weil das die letzte Anweisung war . Aber das war natürlich nicht der Fall.

Naja ich weiß es nicht mehr es ist nicht möglich die Funktionen gets() und fgets() ohne Probs zu nutzen.

Gruß Sector

Caveman
20-12-2005, 21:17
Bei mir geht's.
Du machst irgendwas anderes falsch.

Sector1379
20-12-2005, 21:31
Bei mir geht's.
Du machst irgendwas anderes falsch.

Tja dann gib mir doch mal einen Tip was ich falsch mache. :confused:

Gruß
Sec

Caveman
20-12-2005, 21:47
Ich habe den Code (Heute 21:29) von Dir hergenommen, habe descFile durch main ersetzt, habe die \n-Zeichen noch eingesetzt und am Schluss noch eine Ausgabe. Danach mit gcc kompiliert und es funktionierte -> gcc (GCC) 4.0.2 20050901 (prerelease) (SUSE Linux)

Sector1379
20-12-2005, 22:04
Mhh also ich weiß mir keinen Rat mehr. Ich glaub ich mach mal nen update vom gcc vielleicht hilfts ja.

Gruß Sec

Caveman
20-12-2005, 22:08
Probier es mal mit g++!
Ist dort das gleiche Problem?
Ich befürchte aber, dass es nichts ändert.

Sector1379
20-12-2005, 22:56
So ich habs !!!

Also ich weiß nicht warum das so ist. Ich habe in meinem Hauptprogramm scanf() Aufrufe die ebenfalls Buchstaben in char Arrays abspeichern. Wenn ich diese entferne und dafür gets einsetze klappts, dann kann ich gets und fgets normal aufrufen.

Woran kann das liegen?? Kann das sein das was im Sys durcheinander gekommen ist?

Gruß

Sec

Sector1379
20-12-2005, 23:21
Also hier mal ein Beispiel Code der bei mir nicht läuft.


#include <stdio.h>

int main(void)
{
char satz[81], satz2[20];

printf("Bitte geben sie einen Satz ein:");
scanf("%s", &satz);



printf("\nBitte geben sie einen zweiten Satz ein:");
gets(satz2);

printf("\n");

}

Gruß Sec

Caveman
21-12-2005, 00:12
Füge nach dem scanf dies ein:

fflush(stdin); Das löscht Dir dann das \n-Zeichen aus dem Standardeingabepuffer, das dort noch steht und Du dann gesehen hast.
:cool:

peschmae
21-12-2005, 06:23
Dass das \n im Eingabebuffer irgendwie weg muss stimmt. Allerdings löscht fflush das nicht. fflush ist für input-Streams schon gar nicht erst definiert und wenn das irgendwas bewirken sollte ist das ein platformabhängiger Zufall.
(Siehe auch: http://www.eskimo.com/~scs/C-faq/q12.26.html)

Was hingegen funktioniert ist ein
getchar();
vor dem gets() um eben jenes \n auszulesen.

Allerdings solltest du gets() wirklich nicht benutzen - da muss der User nur einen Input eingeben der länger ist als dein satz2[20]-Array und schon hast du einen Buffer-Overflow. Gleiches Problem auch bei scanf("%s");
Darum solltest du besser fgets verwenden weil du dort die Grösse angeben kannst bis zu der gelesen wird.

MfG Peschmä

Caveman
21-12-2005, 08:28
Hab mit fflush nie Probleme dieser Art gehabt (Sollte funktionieren).
Und auch gets() sollte beenden, sobald die Anzahl Zeichen gelesen wurde, die mit dem 2.Parameter übergiben wurde (oder ein Neue-Zeile-Zeichen kommt).


Edit: Aussage gestrichen, hab's gerade selbst geprüft. So funktioniert es nicht.

Sector1379
21-12-2005, 09:38
Mhh also wenn ich ehrlich bin funktioniert das immer noch nicht richtig.
Ich habe ein fflush(stdin) probiert dann ein getchar(). Das fflush() bringt leider gar nichts und das getchar() wartet auf die eingaben und dann wird danach halt fgets() übersprungen :rolleyes: .

Habt ihr vielleicht noch einen Tip bzw. ist das überhaupt ein bekanntes Problem???

Gruß

Sec

Caveman
21-12-2005, 15:05
#include <stdio.h>
#include <stdlib.h>

# define BUFFERSIZE 80

int main (void)
{
char progname[BUFFERSIZE];
char satz[BUFFERSIZE];
char author[BUFFERSIZE];

printf("*** Please answer the questions ***\n");

printf("*Programm Name: \n");
scanf("%s",&progname);

getchar();

printf("*Author Name: \n");
fgets(author,BUFFERSIZE,stdin);

printf("*Please make a short description (q for exit):\n");
fgets(satz,BUFFERSIZE,stdin);

printf(" - %s - %s - %s",progname,author,satz);
}
So funktioniert's bei mir. Allerdings nur, wenn man nicht zuviele Zeichen eingibt.

Anmerkungen:
In scanf darf kein \n stehen.
Schreibt man dort zwischen % und s den Wert 80 (BUFFERSIZE), dann kann man zwar die Eingabe beschränken, der Rest würde dann allerdings in der nächsten Variable stehen.

Wenn Du wirklich nicht weißt, wieviel jemand eingeben wird. Dann solltest Du am besten mit Vektoren arbeiten.

schönen Gruß
Caveman

Caveman
21-12-2005, 15:39
scanf("%[^\n]s",progname); Den getchar() erspart dies allerdings auch nicht, aber man kann damit mehrere Wörter einlesen (Jedes Zeichen, das nicht \n ist).

rgubatz
22-12-2005, 19:44
Hallo zusammen,
das ist doch mal eine schöne Gelegenheit, sich nach Alternativen umzusehen!
Die libc stinkt zum Himmel! C ist eine wunderschöne Sprache, man muss allerdings das Werkzeug zu nutzen wissen. Das die libc hier Hauptverantwortlich für manchen Fehler ist, kann man an diesem Beispiel schön sehen.
Wie liest man nun einen beliebig! langen String ein?
Wie kann ich solche Frickelwulste wie dieses hier vermeiden?


#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#endif
#if HAVE_STRING_H
#if !STDC_HEADERS && HAVE_MEMORY_H
#include <memory.h>
#endif
#include <string.h>
#endif
#if HAVE_STRINGS_H
#include <strings.h>
#endif
#if HAVE_INTTYPES_H
#include <inttypes.h>
#else
#if HAVE_STDINT_H
#include <stdint.h>
#endif
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif


Warum muss man sich 30 Jahre nach dem definieren einer Programmiersprache immernoch mit solchen Sachen rumärgern?
Warum basieren die meisten Programme auf der libc?
Hier kommt die Lösung: http://www.fefe.de/libowfat/
Und so liesst man mit der libowfat einen beliebig langen String von stdin:

buffer_getnewline_sa(buffer_0,sa);
Und die libowfat kann mehr! In meinen Programmen ersetzt sie komplett die libc. Hier mal ein Paar Beispiele:


/* Dateien öffnen */
file=open_write(filename);
/* Einen String sicher ablegen (ohne nullbytegefrickel) */
stralloc sa;

stralloc_init(&sa);
stralloc_ready(&sa,1024);
buffer_get_new_token_sa(buffer_0,&sa,";,.",3);
stralloc_free(&sa);
/* und solche Sachen sind einfach schoen, auch mit nullbyte */
dest[fmt_humank(dest, sb.st_size)] = 0;
buffer_putsflush(buffer_1, dest);

Und immer dran denken: Kritik ist kein Angriff, sondern eine Chance sich zu verbessern!

Gruss Rene