Ich versuche, ein Programm dazu zu bringen, dass ein Benutzer ein Wort oder Zeichen eingibt, es speichert und dann druckt, bis der Benutzer es erneut eingibt und das Programm beendet. Mein Code sieht folgendermaßen aus:
#include <stdio.h>
int main()
{
char input[40];
char check[40];
int i=0;
printf("Hello!\nPlease enter a word or character:\n");
gets(input);
printf("I will now repeat this until you type it back to me.\n");
while (check != input)
{
printf("%s\n", input);
gets(check);
}
printf("Good bye!");
return 0;
}
Das Problem ist, dass ich immer wieder den Druck der Eingabezeichenfolge erhalte, auch wenn die Eingabe des Benutzers (Prüfung) mit dem Original (Eingabe) übereinstimmt. Vergleiche ich die beiden falsch?
gets( )
wurde aus dem Standard entfernt. Verwenden Siefgets( )
stattdessen.strcmp()
Null zurück, wenn seine Eingaben gleich sind, erklärt, wie Zeichenfolgen auf Gleichheit, Ungleichheit, kleiner als, größer als, kleiner als oder gleich und größer als oder gleich verglichen werden. Nicht alle Zeichenfolgenvergleiche dienen der Gleichheit. Vergleiche zwischen Groß- und Kleinschreibung unterscheiden sich wieder. Andere spezielle Vergleiche (z. B. Wörterbuchreihenfolge) erfordern spezialisiertere Komparatoren, und es gibt reguläre Ausdrücke für noch komplexere Vergleiche.gets()
ist ein No-Go. Es wurde auch seit C11 aus dem Standard entfernt -> Bitte lesen Sie Warum ist die Funktion gets so gefährlich, dass sie nicht verwendet werden sollte?Antworten:
Sie können Zeichenfolgen nicht (sinnvoll) mit
!=
oder vergleichen==
. Sie müssen Folgendes verwendenstrcmp
:Der Grund dafür ist , weil
!=
und==
nur die Basisadressen dieser Strings vergleichen. Nicht der Inhalt der Zeichenfolgen selbst.quelle
while (strcmp(check, input))
ist ausreichend und gilt als gute Praxis.Ok ein paar Dinge:
gets
ist unsicher und sollte durch ersetzt werden,fgets(input, sizeof(input), stdin)
damit Sie keinen Pufferüberlauf bekommen.Als nächstes müssen Sie zum Vergleichen von Zeichenfolgen Folgendes verwenden
strcmp
, wobei ein Rückgabewert von 0 angibt, dass die beiden Zeichenfolgen übereinstimmen. Die Verwendung der Gleichheitsoperatoren (dh!=
) vergleicht die Adresse der beiden Zeichenfolgen im Gegensatz zu den darin enthaltenen Personenchar
.Beachten Sie auch, dass in diesem Beispiel zwar kein Problem verursacht wird,
fgets
das Zeilenumbruchzeichen jedoch auch'\n'
in den Puffern gespeichert wird .gets()
nicht. Wenn Sie die Benutzereingabe vonfgets()
mit einem Zeichenfolgenliteral vergleichen"abc"
, würde es niemals übereinstimmen (es sei denn, der Puffer war zu klein,'\n'
damit er nicht hineinpasst).quelle
fgets()
, liegt die Zeichenfolge möglicherweise daran,"abc\n"
dassfgets()
die neue Zeile beibehalten wird. Wenn Sie dies mit vergleichen"abc"
, erhalten Sie aufgrund des Unterschieds zwischen einem Null-Byte-Abschluss"abc"
und dem Zeilenumbruch in den gelesenen Daten "ungleich" . Sie müssen also die Newline zappen. Der zuverlässige einzeilige Weg, dies zu tun,buffer[strcspn(buffer, "\n")] = '\0';
hat den Vorteil, dass er korrekt funktioniert, unabhängig davon, ob sich Daten im Puffer befinden oder ob diese Daten mit einem Zeilenumbruch enden oder nicht. Andere Möglichkeiten zum Zappen der Newline stürzen leicht ab.Verwenden Sie
strcmp
.Dies ist in der
string.h
Bibliothek und ist sehr beliebt.strcmp
Geben Sie 0 zurück, wenn die Zeichenfolgen gleich sind. Sehen Sie dies für eine bessere Erklärung dessen, wasstrcmp
zurückkehrt.Grundsätzlich müssen Sie Folgendes tun:
oder
oder
Sie können überprüfen , dies , ein Tutorial auf
strcmp
.quelle
Sie können Arrays nicht direkt so vergleichen
Sie sollten sie char-by-char vergleichen. Dazu können Sie eine Funktion verwenden und einen booleschen Wert (True: 1, False: 0) zurückgeben. Dann können Sie es in der Testbedingung der while-Schleife verwenden.
Versuche dies:
quelle
checker
Funde'\0'
in einer der Saiten, ist es nicht die für eine andere Zeichenfolge zu überprüfen'\0'
. Die Funktion gibt zurück1
("gleich"), auch wenn eine Zeichenfolge nur das Präfix der anderen ist (z. B."foo"
und"foobar"
).||
anstelle von verwenden&&
.Willkommen zum Konzept des Zeigers. Generationen von Programmieranfängern fanden das Konzept schwer fassbar, aber wenn Sie sich zu einem kompetenten Programmierer entwickeln möchten, müssen Sie dieses Konzept schließlich beherrschen - und darüber hinaus stellen Sie bereits die richtige Frage. Das ist gut.
Ist Ihnen klar, was eine Adresse ist? Siehe dieses Diagramm:
Im Diagramm wird die Ganzzahl 1 unter der Adresse 0x4000 gespeichert . Warum an einer Adresse? Weil der Speicher groß ist und viele ganze Zahlen speichern kann, so wie eine Stadt groß ist und viele Familien beherbergen kann. Jede Ganzzahl wird an einem Speicherort gespeichert, da jede Familie in einem Haus wohnt. Jeder Speicherort wird durch eine Adresse identifiziert , wie jedes Haus durch eine Adresse identifiziert wird.
Die beiden Felder im Diagramm repräsentieren zwei unterschiedliche Speicherplätze. Sie können sich sie vorstellen, als wären sie Häuser. Die Ganzzahl 1 befindet sich im Speicher unter der Adresse 0x4000 (denken Sie an "4000 Elm St."). Die Ganzzahl 7 befindet sich im Speicher unter der Adresse 0x4004 (denken Sie an "4004 Elm St.").
Sie dachten, dass Ihr Programm die 1 mit der 7 vergleicht, aber das war es nicht. Es wurde der 0x4000 mit dem 0x4004 verglichen. Was passiert also, wenn Sie diese Situation haben?
Die beiden Ganzzahlen sind gleich, aber die Adressen unterscheiden sich. Ihr Programm vergleicht die Adressen.
quelle
Wenn Sie versuchen, die Zeichenfolgen zu vergleichen, vergleichen Sie sie in Bezug auf jedes Zeichen. Hierfür können Sie die integrierte String-Funktion strcmp (input1, input2) verwenden. und Sie sollten die aufgerufene Header-Datei verwenden
#include<string.h>
Versuchen Sie diesen Code:
quelle
Lassen Sie uns tiefer graben, um zu sehen, warum dies
check != input
nicht ausreicht .In C ist string eine Standardbibliotheksspezifikation.
input
oben ist keine Zeichenfolge .input
ist Array 40 von char .Der Inhalt von
input
kann zu einer Zeichenfolge werden .In den meisten Fällen wird ein Array, wenn es in einem Ausdruck verwendet wird, in die Adresse seines ersten Elements konvertiert.
Das Folgende konvertiert
check
undinput
zu ihren jeweiligen Adressen des ersten Elements, dann werden diese Adressen verglichen.Um Zeichenfolgen zu vergleichen , müssen wir diese Adressen verwenden und dann die Daten betrachten, auf die sie verweisen.
strcmp()
macht den Job . §7.23.4.2Code kann nicht nur feststellen, ob die Zeichenfolgen dieselben Daten enthalten, sondern auch, welche größer / kleiner ist, wenn sie sich unterscheiden.
Das Folgende gilt, wenn sich die Zeichenfolge unterscheidet.
Weitere Informationen finden Sie unter Erstellen meiner eigenen
strcmp()
Funktionquelle
Dies ist eine sehr einfache Lösung, bei der Sie Ihre Ausgabe nach Ihren Wünschen erhalten.
quelle
gets();
seit C11 nicht mehr Teil von Standard C.strcmp(s1,s2)
ist UB, da ders2
Inhalt zunächst nicht angegeben wird.