Benutzereingabe j/ n mithilfe von strcmp und const char*s

  • C

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von Bartosz.

    Benutzereingabe j/ n mithilfe von strcmp und const char*s

    Moin,

    ich habe eine kurze Frage zu C:

    Der Benutzer soll nur ein Zeichen (ja / nein also j oder n) eingeben.

    Leider läuft die If-Abfrage schief (Zeile 34) oder die enthaltene strcmp-Funktion. Ich habe einen Haltepunkt gesetzt und Studio sagt mir, dass beide Variablen 'j' enthalten. Das Programm läuft dennoch ins Else.

    Mit

    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdin, NULL, _IONBF, BUFSIZ);

    mache ich den Puffer leer, für den Fall, dass der Benutzer bei einer vorherigen Abfrage zu viel eingegeben hatte, was nun stören würde.

    Hier der Code. Ich glaube eh, dass ich nicht so viel Code brauche, daher bin ich für alles offen ^^
    Visual Studio Professional 2019 (16.3.2)
    Windows 8.1 64 bit

    C-Quellcode

    1. [size=10]#include <stdio.h>
    2. #include <iostream>
    3. #include <Windows.h>
    4. #pragma warning(disable:4996) //Visual Studio will scanf_s sehen
    5. int main(void)
    6. {
    7. ShowWindow(GetConsoleWindow(), SW_MAXIMIZE);
    8. system("color F0");
    9. double a, b, c;
    10. double eingegebene_Punkte_y[3];
    11. double eingegebene_Punkte_x[3];
    12. char ja_nein[1];
    13. int scanf_Error = 0;
    14. printf("Gib die Punkte f\x81 \br \"f(...) = ...\" wie folgt ein: x.x TAB y.y\n");
    15. for (int i = 0; i < 3; i++)
    16. {
    17. do
    18. {
    19. scanf_Error = scanf("%lf\t%lf", &eingegebene_Punkte_x[i], &eingegebene_Punkte_y[i]);
    20. } while (scanf_Error < 2);
    21. }
    22. printf("f(%.1lf) = %.1lf\nf(%.1lf) = %.1lf\nf(%.1lf) = %.1lf\nj / n? ", eingegebene_Punkte_x[0], eingegebene_Punkte_y[0], eingegebene_Punkte_x[1], eingegebene_Punkte_y[1], eingegebene_Punkte_x[2], eingegebene_Punkte_y[2]);
    23. setvbuf(stdin, NULL, _IONBF, 0);
    24. setvbuf(stdin, NULL, _IONBF, BUFSIZ);
    25. scanf("%c", &ja_nein[0]);
    26. const char* P_ja = new char('j');
    27. const char* P_ja_nein = new char(ja_nein[0]); //on the Heap
    28. if (strcmp(P_ja_nein, P_ja) == 0)
    29. {
    30. printf("Gut!\n");
    31. }
    32. else
    33. {
    34. printf("Dann nochmal von vorn.\n");
    35. system("pause");
    36. return 0;
    37. }
    38. delete P_ja;
    39. delete P_ja_nein;
    40. system("pause"); //Was gibt's hier besseres?
    41. return 0;
    42. }
    43. [/size]




    Viele Grüße und bleibt gesund
    Hi, Bartosz!

    Das erste was mir hier auffällt ist, dass du C mit C++ mischt!
    Der Header iostream ist nämlich ein C++ Header.
    Außerdem verwendest du new und delete was auch nur C++ Operatoren sind.
    Es ist natürlich legitim zu fusionieren, aber es kann unübersichtlich werden.
    Das was du da hast ist also ein C++ Projekt mit C Komponenten!

    So viel dazu.
    Es ist absolut unnötig btw. das du die Zeichenketten im Heap allozierst, da du sie ja nicht modifizierst. String literals (meistens) werdem weder in den Heap noch den Stack platziert sondern direkt in die Binary eingebettet. (so wie immer, gibt es auch hier Ausnahmen, je nach Platform und Compiler)
    Da du aber eh nur char verwendest, brauchst du nicht einmal strings und kannst direkt "strcmp("j", &ja_nein)" verwenden.

    Noch besser wäre es davor auch noch "ja_nein" mit "tolower" zu behandeln.

    "char ja_nein[1];" ist Sinnfrei, es reicht es nur als ganz normale Variable zu deklarieren.

    Die Adresse bekommst du dann auch ohne subscript operator.

    Und auch wenn es ein Array ist, "&ja_nein[0]" ist auch unnötig, "[0]" und "&" kannst du weglassen da ein array immer ein Pointer ist und auf das erste Element Zeigt!

    Wo jetzt genau das Problem liegt kann ich dir nicht sagen, bei mir funktioniert es einwandfrei aber du solltest mal ein wenig aufräumen und dann noch einmal probieren.

    Lg Elanda :)
    ----------------------------------------------------------------------------------------------------------------------

    Hier könnte meine Signatur stehen, aber die ist mir abfußen gekommen.

    ----------------------------------------------------------------------------------------------------------------------
    Hi @Elanda Ich danke dir für deine ausführliche Antwort! Das, was du erkennst, sind meine vielen, kleinen Baustellen in C.

    - stimmt, ein C++ Projekt, in dem ich nur C mache. Geht bei Visual Studio nicht anders. Also nicht dass ich wüsste.
    - iostream habe ich bereits entfernt -> ich mache nur C

    - das mit dem Zeichenketten im Heap alloziieren habe ich irgendwann zu
    Anfängerzeiten bei Stack******** gesehen; Das ist bei mir ein spezielles Thema, weil man dort so viel liest und nicht mehr weiß, was jetzt gut und was schlecht ist.

    -strcmp("j", &ja_nein) Ich meine, da hatte in einen Fehler. Kann aber auch sein, dass ich zu voreilig war.

    - char ja_nein[1];" ist Sinnfrei stimmt :D Ist raus.

    Nach dem ich Post #1 geschrieben habe, habe ich auch umgebaut. Von daher brauche ich keine Pointer und kein Delete mehr.

    C-Quellcode

    1. #include <stdio.h>
    2. #include <Windows.h>
    3. #include <wchar.h>
    4. #pragma warning(disable:4996) //Visual Studio will scanf_s sehen
    5. int main(void)
    6. {
    7. ShowWindow(GetConsoleWindow(), SW_MAXIMIZE);
    8. system("color F0");
    9. double a, b, c;
    10. double eingegebene_Punkte_y[3];
    11. double eingegebene_Punkte_x[3];
    12. int scanf_Error = 0;
    13. printf("Gib die Punkte f\x81 \br \"f(...) = ...\" wie folgt ein: x.x TAB y.y\n");
    14. for (int i = 0; i < 3; i++)
    15. {
    16. do
    17. {
    18. scanf_Error = scanf("%lf\t%lf", &eingegebene_Punkte_x[i], &eingegebene_Punkte_y[i]);
    19. } while (scanf_Error < 2);
    20. }
    21. printf("f(%.1lf) = %.1lf\nf(%.1lf) = %.1lf\nf(%.1lf) = %.1lf\nj / n? ", eingegebene_Punkte_x[0], eingegebene_Punkte_y[0], eingegebene_Punkte_x[1], eingegebene_Punkte_y[1], eingegebene_Punkte_x[2], eingegebene_Punkte_y[2]);
    22. setvbuf(stdin, NULL, _IONBF, 0);
    23. setvbuf(stdin, NULL, _IONBF, BUFSIZ);
    24. wint_t Ja_Nein = _getwch();
    25. if (Ja_Nein == 106) //j
    26. {
    27. printf("Gut!\n");
    28. }
    29. else
    30. {
    31. printf("\nDann nochmal von vorn.\n");
    32. system("pause");
    33. return 0;
    34. }
    35. system("pause"); //Was gibt's hier besseres?
    36. return 0;
    37. }


    Ich musste übrigens _getwch() statt getch() hernehmen, weil mein x64 WIndows 8.1 getch() nicht mag. Ist ein bekannter Fehler. Getch() returnt 2 Character wenn man 1 eintippt. Es ist noch '\0' dabei.

    Könntest du mir bitte sagen, was ich noch aufräumen kann?
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.