fgets funktioniert nach scanf nicht

7
%Vor%

Nachdem ich "loops" eingegeben habe, wurde "s1" automatisch eine Leerzeile zugewiesen. Wie ist es passiert? Ich bin mir sicher, dass meine Tastatur gut funktioniert.

    
Vayn 06.05.2011, 23:37
quelle

6 Antworten

15

scanf() liest genau das, woran Sie es gefragt haben, und belässt das folgende \n vom Ende dieser Zeile im Puffer, wo fgets() es liest. Entweder tun Sie etwas, um die neue Zeile zu konsumieren, oder (meine bevorzugte Lösung) fgets() und dann sscanf() von dieser Zeichenfolge.

    
geekosaur 06.05.2011, 23:41
quelle
3

scanf lässt Leerzeichen im Eingabepuffer einschließlich Zeichen für neue Zeilen. Um fgets zum Lesen der nächsten Zeile zu verwenden, müssen Sie den Rest der aktuellen Zeile manuell entfernen:

%Vor%     
hugomg 07.05.2011 00:08
quelle
2

Vayn,

Geekoaur hat Ihre Frage gut beantwortet, ich weise nur auf ein anderes "Problem" mit Ihrem Code hin.

Die Zeile s1[strlen(s1)] = 's1'; ist eine no-op , wenn s1 bereits korrekt null beendet ist, BEVOR sie ausgeführt wird.

Aber wenn strlen NICHT bereits richtig null beendet ist, BEVOR diese Zeile ausgeführt wird (und Sie Pech haben), wird dies verursachen:

Dies liegt daran, dass string[sizeof(string)]='string[SIZE_OF_STRING]'; basicaly den Index des vorhandenen Null-Terminators findet und diesen zurückgibt! Hier ist eine gültige, nicht optimierte Implementierung von strlen:

%Vor%

Also ... Wenn Sie sich wirklich Sorgen machen, dass Strings NICHT nullterminiert sind, dann tun Sie etwas wie:

  • SIZE_OF_STRING für lokale automatische Zeichenfolgen (wobei der Compiler die Größe der Zeichenfolge "kennt");
  • oder #define für alle anderen Zeichenfolgen, wobei memset(string, NULL, SIZE_OF_STRING); (am häufigsten) eine DirtyFunction(/*out*/string) 'd Konstante oder eine Variable ist, die Sie speziell beibehalten, um die aktuelle SIZE (nicht die Länge) eines dynamisch zugewiesenen zu speichern Zeichenfolge.

Und wenn Sie WIRKLICH, WIRKLICH, wirklich besorgt sind, dass Strings nicht null-terminiert sind (wie Sie es mit "schmutzigen" libary-Methoden (wie ATMI von Tuxedo zum Beispiel) zu tun haben, dann ALSO " löschen Sie "Ihre" Return-Strings ", bevor Sie sie an die verdächtigen Bibliotheksmethoden übergeben:

  • vorher: string[SIZE_OF_STRING]='strncpy'
  • rufen Sie auf: strlcpy ;
  • nach: strnlen

SIG11's sind ein komplettes biatch zu finden, weil (außer Sie "haken" sie mit einem signal-processor und sagen Sie es anders, sie verursachen Unix, um Ihr Programm hart zu beenden, so dass Sie nichts (nach der Tatsache) anmelden können, um herauszufinden, wo-in-der-Hölle-did- that-come-from ... besonders in Anbetracht der Tatsache, dass die Codezeile, die den SIG11 auslöst, in vielen Fällen der tatsächlichen Ursache der Zeichenfolge, die ihren Nullabschluss verliert, nicht näher kommt.

Macht das für Sie Sinn?

Prost Kumpel. Keith.

PS: ACHTUNG: %code% NICHT immer nullterminate ... du meinst wahrscheinlich %code% . Ich habe das auf die harte Tour gelernt ... als ein 60 Millionen Dollar Billing-Lauf abgestürzt ist.

BEARBEITEN:

Zur Erinnerung: Hier ist eine "sichere" (nicht optimierte) Version von strlen, die ich %code% nennen werde (ich denke, das sollte in stdlib sein. Seufz.).

%Vor%     
corlettk 07.05.2011 00:29
quelle
1

Ich weiß, das ist sehr alt. Ich bin neu in c und wollte meine Methode überprüfen, die getchar verwendet:

%Vor%     
Michele 07.02.2014 12:46
quelle
1

einfach gesagt      scanf("%d\n",&loops);

statt       scanf("%d",&loops);

    
phantom_ab 09.09.2016 00:27
quelle
0

Das Folgende funktioniert, wenn fgets() nach der Verwendung von scanf()

"übersprungen" wird

Nachdem ich gesagt habe:

%Vor%

Sprich:

%Vor%

Dies speichert alles, was im Eingabepuffer übrig ist, in die Müllvariable.

Dadurch wird der Eingabepuffer gelöscht und Sie können fgets() später verwenden.

BEARBEITEN: Ich habe kürzlich erfahren, dass es eine einfachere Lösung als die obige gibt. Wenn Sie getchar () nach scanf () sagen, können Sie fgets () ohne Probleme verwenden. getchar () erhält das nächste Zeichen im Eingabepuffer, in diesem Fall '\ n'. Sobald Sie '\ n' aus dem Eingabepuffer entfernen, sollten fgets gut funktionieren.

    
Coder Typist 23.02.2018 00:32
quelle

Tags und Links