Tabelle mit C ausgeben

  • C

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von a.b_om.

    Tabelle mit C ausgeben

    Hallo zusammen

    Ich komme nicht weiter.
    Ich möchte meine doppelt verkettete Liste wie eine Tabelle ausgeben.

    Die Zeichenlaenge sind unterschiedlich und deshalb, kann ich es nicht einfach mit fixen Werte machen.

    Aber wie bekomme ich das hin, dass es wirklich eine Tabelle anzeigt, mit allen Einträgen in der Liste?

    Mein Code zum ausgeben:
    Spoiler anzeigen

    C-Quellcode

    1. YugiohKarte YugiohKarteAusgeben(YugiohKarte ersteYugiohKarte) {
    2. printf("\nMoechtest du alle Karten ausgeben oder nur eine bestimmte? (Ja/Nein): ");
    3. char antwort[MAX];
    4. fgets(antwort, MAX, stdin);
    5. if (antwort[0] == 'J' && antwort[1] == 'a')
    6. {
    7. do
    8. {
    9. if (ersteYugiohKarte.Beschreibung[0] == 'D')
    10. {
    11. printf("\nEs gibt keine Yugiohkarten zum ausgeben.");
    12. }
    13. else
    14. {
    15. YugiohKarte* jetzigeYugiohKarte = &ersteYugiohKarte;
    16. printf("| Kartenname | Kartenart | Stufe | Rang | Pendelstufe | Link | ATK | DEF | Eigenschaft | Monstertyp | Kartentyp | Beschreibung |\n");
    17. printf("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
    18. do
    19. {
    20. printf("| ");
    21. printf(jetzigeYugiohKarte->Name);
    22. } while (jetzigeYugiohKarte->pNext != NULL);
    23. }
    24. break;
    25. } while (true);
    26. }
    27. else if (antwort[0] == 'N' && antwort[1] == 'e' && antwort[2] == 'i' && antwort[3] == 'n')
    28. {
    29. }
    30. return ersteYugiohKarte;
    31. }


    *Topic verschoben*

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Hallo a.b_om,

    Das erste das mir auffällt ist diese mir unverständliche do while Schleife, du setzt sie auf true und brichst sie gleich wieder ab.
    Kann auch sein das ich den Punkt hier übersehe da ich nur mit C++ arbeite, villeicht ist das so ja ein C Ding.

    Punkt 2, die zweite Schleife, wenn ich das richtig sehe änderst du nie die abzufragende Adresse von "jetzigeYugiohKarte", du frägst einfach nur ab ob "pNext" irgendwohin zeigt, lässt aber "jetzigeYugiohKarte" unverändert.
    Das wird darin resultieren, dass für eine unbestimmt lange Zeit immer und immer wieder dieselbe Karte ausgegeben wird und dein Programm, sofern keine anderen Umstände bestehen, endlos laufen wird.
    Soweit ich das verstehe ist pNext die Adresse zur nächsten Karte?
    Dann mach doch einfach 'while(jetzigeYugiohKarte = jetzigeYugiohKarte->pNext)', dies wird den nächsten Wert zuweisen und gleichzeitig abfragen ob der Wert immer noch valide ist!

    Und drittens, ich bin wie gesagt nicht sehr versiert in Sachen C und besonders string Management bringt mich immer wieder aus dem Konzept, ich hätte da aber einen Tipp.
    Definiere irgendwo die verschiedenen Zeichenlängen der Tabellenheader, der Text der in die individuellen Zellen ausgegeben werden soll wird dann auf die Länge geprüft, ist es zu groß verkürzt du den Text mit '...' am Ende, ist es kürzer kannst du die Differenz der noch zu brauchenden Zeichen für die Headerlänge errechnen und mit Leerzeichen ausfüllen!

    ~ Elanda

    Edit: Kleiner Nachtrag, bei der Abfrage Ja/Nein wird er nur validieren wenn Ja oder Nein anfänglich groß geschrieben wird, da 'j', 'J', 'n' und 'N' andere Code Points besitzen.
    Sowieso würde ich eher nur auf J, j oder N, n überprüfen also "(J)a/(N)ein", aber wie du das bevorzugst bleibt dir überlassen. :)
    ----------------------------------------------------------------------------------------------------------------------

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

    ----------------------------------------------------------------------------------------------------------------------

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Elanda“ ()

    @Elanda

    Elanda schrieb:

    Das erste das mir auffällt ist diese mir unverständliche do while Schleife, du setzt sie auf true und brichst sie gleich wieder ab.
    Kann auch sein das ich den Punkt hier übersehe da ich nur mit C++ arbeite, villeicht ist das so ja ein C Ding.

    Nein, das ist kein C Ding. Dort kommen noch mehr Codezeilen hin. Bin aber noch nicht so weit.

    Elanda schrieb:

    Punkt 2, die zweite Schleife, wenn ich das richtig sehe änderst du nie die abzufragende Adresse von "jetzigeYugiohKarte", du frägst einfach nur ab ob "pNext" irgendwohin zeigt, lässt aber "jetzigeYugiohKarte" unverändert.
    Das wird darin resultieren, dass für eine unbestimmt lange Zeit immer und immer wieder dieselbe Karte ausgegeben wird und dein Programm, sofern keine anderen Umstände bestehen, endlos laufen wird.
    Soweit ich das verstehe ist pNext die Adresse zur nächsten Karte?
    Dann mach doch einfach 'while(jetzigeYugiohKarte = jetzigeYugiohKarte->pNext)', dies wird den nächsten Wert zuweisen und gleichzeitig abfragen ob der Wert immer noch valide ist!

    Die Methode ist nur zur Ausgabe da und ich werde deine Methode mal ausprobieren.

    Elanda schrieb:

    Und drittens, ich bin wie gesagt nicht sehr versiert in Sachen C und besonders string Management bringt mich immer wieder aus dem Konzept, ich hätte da aber einen Tipp.
    Definiere irgendwo die verschiedenen Zeichenlängen der Tabellenheader, der Text der in die individuellen Zellen ausgegeben werden soll wird dann auf die Länge geprüft, ist es zu groß verkürzt du den Text mit '...' am Ende, ist es kürzer kannst du die Differenz der noch zu brauchenden Zeichen für die Headerlänge errechnen und mit Leerzeichen ausfüllen!

    Wie, bin auch nicht verisiert mit C. Ist ein Steilstart mit dem Projekt. Brauche dementsprechend auch viel Hilfe.

    Elanda schrieb:

    Edit: Kleiner Nachtrag, bei der Abfrage Ja/Nein wird er nur validieren wenn Ja oder Nein anfänglich groß geschrieben wird, da 'j', 'J', 'n' und 'N' andere Code Points besitzen.
    Sowieso würde ich eher nur auf J, j oder N, n überprüfen also "(J)a/(N)ein", aber wie du das bevorzugst bleibt dir überlassen.

    Was ist, wenn der Benutzer "Jey" oder etwas anderes eingibt?

    Edit:
    char Arrays in C sind schon etwas kompliziertes. Hätte es Strings, würde ich sie brauchen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „a.b_om“ ()

    a.b_om schrieb:

    Was ist, wenn der Benutzer "Jey" oder etwas anderes eingibt?

    Das ist dann das Problem des Nutzers, du gibst klare Anweisungen. (Ja/Nein)
    Wenn der Benutzer die nicht einhält obwohl sie klar verständlich sind, stellt sich sowieso die Frage ob der Nutzer überhaupt dazu in der Lage ist das Programm zu verwenden.
    Natürlich kannst du stapelweise Synonyme und Slang-terms einbauen, allerdings verstehe ich da den Sinn nicht dahinter wenn du klar und deutlich angeben kannst was der Benutzer zu tun hat!

    Edit:
    Du könntest, im Falle der falschen Eingabe, eine Antwort hinterlassen mit dem Hinweis zur Neueingabe!
    ----------------------------------------------------------------------------------------------------------------------

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

    ----------------------------------------------------------------------------------------------------------------------

    a.b_om schrieb:

    Ja das ist mir klar. Aber wenn er es aus Spass etwas Falsches eingibt, kann ich das nicht abfangen.

    Natürlich kannst du es abfangen, mit einer einfachen If-else Anweisung.

    a.b_om schrieb:

    Aber wie kriege ich das mit der Tabelle hin?

    Nun, nehmen wir mal an die Spalte Kartenname sieht so aus: |------Kartenname------|
    Abzüglich der Seperatoren, wären das dann 22 Zeichen.
    Nehmen wir an deine Karte wäre "Schwarzes Loch" (ja ich kenne mich ein wenig aus),
    das wären dann 14 Zeichen, ergo fehlen noch 8 Zeichen bis zum nächsten Seperator, die füllst du mit Leerzeichen aus. (falls das funktioniert, es gibt genügende Anwendungen welche serielle Leerzeichen tragischerweise einfach löschen)
    Nun angenommen der Name ist doch etwas üppiger, dann müssen wir die überschüssigen Zeichen entfernent.
    Dies wird meistens, wenn nicht sogar immer, mit drei Punkten dargestellt.
    Also zum Beispiel "Irgendein Drache aus dem Spiel" hat 30 Zeichen, demnach müsstest du dies auf 22 Zeichen trimmen.
    Allerdings auf 19 Zeichen, da du für die 3 Punkte auch noch 3 Zeichen bräuchtest.

    Natürlich kommt dann noch margin und alignment dazu, aber du solltest einmal die Grundausführung bereitmachen.
    Das machst du dann mit allen Spalten so!
    ----------------------------------------------------------------------------------------------------------------------

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

    ----------------------------------------------------------------------------------------------------------------------
    @Elanda
    Ich werde es versuchen.

    Edit:
    Ich kann es nicht versuchen, weil ich einen Fehler habe.
    Der Fehler passiert in Zeile 3-4 siehe Code in Post 1.
    Der zweiter Datensatz, wird irgendwie verändert. Die Werte sind volkommener Blödsinn und deshalb kann ich es nicht versuchen.

    Wenn ihr eine Idee habt, könnt ihr es sagen. Bin seit knapp 2 Tagen das dran. Bisher hat der Fehler keine Einschränkungen bei den Funktionen bewirkt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „a.b_om“ ()

    Ich hab es mal durch meinen Compiler gefüttert da funktionieren 3 - 4 Tadellos.
    Wie groß ist denn MAX?
    Was für ein Fehler tritt denn genau auf?

    Oh und btw. mach doch anstatt von "string[index] == 'char'" einfach strcmp(string1, string2), dann brauchst du nicht jeden einzelnen character einzeln abfragen.
    Sieht ein wenig unschön aus.
    ----------------------------------------------------------------------------------------------------------------------

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

    ----------------------------------------------------------------------------------------------------------------------
    Wenn das größte Wort das du eingibst nein ist, sind 256 Zeichen ein wenig über dem Horizont, denkst du nicht?
    Länge 5 müsste reichen, der Rest wird dann einfach abgeschnitten.

    Das dürfte aber nicht das eigentliche Problem sein.
    Ich habe irgendwie das Gefühl an deiner eigentlichen Fragestellung vorbeigerasselt zu sein.
    Warscheinlich weil ich nicht genau verstanden habe was jetzt das eigentliche Problem hier ist.
    ----------------------------------------------------------------------------------------------------------------------

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

    ----------------------------------------------------------------------------------------------------------------------
    Also jetzt verstehe ich gar nichts mehr, von welcher Struktur redest du?
    Vom Aufbau des codes oder einem struct?
    Und wenn von einem struct, wo greifst du in Zeile 3 oder 4 auf ein struct zu?

    Es wird ein wenig unübersichtlich.
    ----------------------------------------------------------------------------------------------------------------------

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

    ----------------------------------------------------------------------------------------------------------------------
    Na wenn du das gleich mit in deinen ersten Beitrag genommen hättest, wären wir wahrscheinlich jetzt viel weiter.
    Ich zum Beispiel wusste nichts von dem anderen Beitrag, auf das musst du schon hinweisen.

    Egal,
    Stell doch mal den gesamten Dateiinhalt hier rein, ich denke du wirst viel daran geändert haben.
    Und dann zeigst du bitte auch was dir die Konsole ausgibt, wenn das nicht geht weil ein Problem aufgetreten ist, beschreibst du halt das Problem. (damit meine ich eine exception, wenn eine aufgetreten war)

    Edit:
    Jetzt fällt es mir erst auf!
    Gibt es einen Grund wieso du "ersteYugiohKarte" by value und nicht by pointer übergibst? (ich weiß jetzt nicht ob C Referenzen unterstützt)
    Das ist sinnlose Kopierarbeit für nichts.
    ----------------------------------------------------------------------------------------------------------------------

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

    ----------------------------------------------------------------------------------------------------------------------

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Elanda“ ()

    @Elanda
    Sorry, dass ich nicht zurückgeschrieben habe.

    Nein, am Code hat sich nicht viel verändert.

    Wie mache ich dann das mit dem Pointermitgabe.

    Mein kompletter Code:
    Spoiler anzeigen

    C-Quellcode

    1. #include "pch.h"
    2. #include <iostream>
    3. #include <stdio.h>
    4. #include "LinkedList.h"
    5. #define MAX 265
    6. typedef struct YugiohKarte {
    7. char Name[100];
    8. char Kartenart[20];
    9. int Stufe;
    10. int Rang;
    11. int Pendelstufe;
    12. int Link;
    13. char ATK[20];
    14. char DEF[20];
    15. char Eigenschaft[20];
    16. char Monstertyp[40];
    17. char Kartentyp[30];
    18. char Beschreibung[500];
    19. struct YugiohKarte* pNext;
    20. struct YugiohKarte* pPrev;
    21. } strYugiohKarte;
    22. YugiohKarte YugiohKarteErstellen(YugiohKarte ersteYugiohKarte) {
    23. char antwort[MAX];
    24. int anzahlKarten;
    25. YugiohKarte *vorhaerigeYugiohKarte = &ersteYugiohKarte;
    26. do
    27. {
    28. YugiohKarte* pErsteYugiohKarte = &ersteYugiohKarte;
    29. printf("\nWie viele Yugiohkarten moechten Sie erstellen? Bitte geben Sie nur Zahlen ein, sonst kommt es zu einem Absturz.");
    30. fgets(antwort, MAX, stdin);
    31. anzahlKarten = atoi(antwort);
    32. for (int i = 1; i <= anzahlKarten; i++)
    33. {
    34. if (pErsteYugiohKarte->Beschreibung[0] == 'B' && pErsteYugiohKarte->Beschreibung[1] == 'l' && pErsteYugiohKarte->Beschreibung[2] == 'a' && pErsteYugiohKarte->Beschreibung[3] == 'B' && pErsteYugiohKarte->Beschreibung[4] == 'l' && pErsteYugiohKarte->Beschreibung[5] == 'a')
    35. {
    36. ersteYugiohKarte = { "Name", "Kartenart", 1, 0, 0, 0, "ATK", "DEF", "Eigenschaft", "Monstertyp", "Kartentyp", "Beschreibung" };
    37. }
    38. else
    39. {
    40. YugiohKarte naechsteYugiohKarte = { "Name", "Kartenart", 1, 0, 0, 0, "ATK", "DEF", "Eigenschaft", "Monstertyp", "Kartentyp", "Beschreibung2" };
    41. do
    42. {
    43. if (vorhaerigeYugiohKarte->pNext != NULL)
    44. {
    45. vorhaerigeYugiohKarte = vorhaerigeYugiohKarte->pNext;
    46. }
    47. else
    48. {
    49. break;
    50. }
    51. } while (true);
    52. naechsteYugiohKarte.pPrev = vorhaerigeYugiohKarte;
    53. vorhaerigeYugiohKarte->pNext = &naechsteYugiohKarte;
    54. if (vorhaerigeYugiohKarte->pPrev == NULL)
    55. {
    56. ersteYugiohKarte = *vorhaerigeYugiohKarte;
    57. }
    58. printf(" ");
    59. }
    60. }
    61. return ersteYugiohKarte;
    62. } while (true);
    63. }
    64. YugiohKarte YugiohKarteLoeschen(YugiohKarte ersteYugiohKarte) {
    65. return ersteYugiohKarte;
    66. }
    67. YugiohKarte YugiohKarteAusgeben(YugiohKarte ersteYugiohKarte) {
    68. YugiohKarte* pErsteYugiohKarte = &ersteYugiohKarte;
    69. printf("\nMoechtest du alle Karten ausgeben oder nur eine bestimmte? (Ja/Nein): ");
    70. char antwort[MAX];
    71. fgets(antwort, MAX, stdin);
    72. if (antwort[0] == 'J' && antwort[1] == 'a')
    73. {
    74. do
    75. {
    76. if (pErsteYugiohKarte == NULL)
    77. {
    78. printf("\nEs gibt keine Yugiohkarten zum ausgeben.");
    79. }
    80. else
    81. {
    82. int i = 1;
    83. YugiohKarte* jetzigeYugiohKarte = pErsteYugiohKarte;
    84. do
    85. {
    86. printf("\n%i. Yugioh-Karte", i);
    87. printf("\nName: %s", jetzigeYugiohKarte->Name);
    88. printf("\nKartenart: %s", jetzigeYugiohKarte->Kartenart);
    89. printf("\nStufe: %i", jetzigeYugiohKarte->Stufe);
    90. printf("\nRang: %i", jetzigeYugiohKarte->Rang);
    91. printf("\nPendelstufe: %i", jetzigeYugiohKarte->Pendelstufe);
    92. printf("\nLink: %i", jetzigeYugiohKarte->Link);
    93. printf("\nATK: %s", jetzigeYugiohKarte->ATK);
    94. printf("\nDEF: %s", jetzigeYugiohKarte->DEF);
    95. printf("\nEigenschaft: %s", jetzigeYugiohKarte->Eigenschaft);
    96. printf("\nMonstertyp: %s", jetzigeYugiohKarte->Monstertyp);
    97. printf("\nKartentyp: %s", jetzigeYugiohKarte->Kartentyp);
    98. printf("\nBeschreibung: %s\n", jetzigeYugiohKarte->Beschreibung);
    99. i++;
    100. jetzigeYugiohKarte = jetzigeYugiohKarte->pNext;
    101. } while (jetzigeYugiohKarte != NULL);
    102. }
    103. break;
    104. } while (true);
    105. }
    106. else if (antwort[0] == 'N' && antwort[1] == 'e' && antwort[2] == 'i' && antwort[3] == 'n')
    107. {
    108. }
    109. return ersteYugiohKarte;
    110. }
    111. int main()
    112. {
    113. YugiohKarte ersteYugiohKarte = { "N", "K", 1, 0, 0, 0, "A", "D", "E", "M", "K", "BlaBla" };
    114. printf("\nWICHTIG: Bitte maximieren Sie das Fenster, weil es sonst nicht alles richtig darstellt.");
    115. do
    116. {
    117. printf("\nMoechten Sie eine Yugioh-Karten erstellen(YKE), eine Yugioh-Karte loeschen(YKL), eine Yugioh-Karte ausgeben(YKA) oder das Programm schliessen(Prsc):");
    118. char antwort[MAX];
    119. fgets(antwort, MAX, stdin);
    120. if (antwort[0] == 'Y' && antwort[1] == 'K' && antwort[2] == 'E') {
    121. ersteYugiohKarte = YugiohKarteErstellen(ersteYugiohKarte);
    122. }
    123. else if (antwort[0] == 'Y' && antwort[1] == 'K' && antwort[2] == 'L') {
    124. YugiohKarteLoeschen(ersteYugiohKarte);
    125. }
    126. else if (antwort[0] == 'Y' && antwort[1] == 'K' && antwort[2] == 'A') {
    127. YugiohKarteAusgeben(ersteYugiohKarte);
    128. }
    129. else if (antwort[0] == 'P' && antwort[1] == 'r' && antwort[2] == 's' && antwort[3] == 'c') {
    130. return 0;
    131. }
    132. else
    133. {
    134. printf("Bitte geben Sie eine Abkuerzung ein!");
    135. }
    136. } while (true);
    137. }
    Indem Du die Adresse an die Prozeduren übergibst:

    C-Quellcode

    1. Void Main() {
    2. //...
    3. if (antwort[0] == 'Y' && antwort[1] == 'K' && antwort[2] == 'E') {
    4. ersteYugiohKarte = YugiohKarteErstellen(&ersteYugiohKarte);
    5. }
    6. }
    7. YugiohKarte YugiohKarteAusgeben(YugiohKarte* ersteYugiohKarte) {
    8. YugiohKarte* pErsteYugiohKarte = ersteYugiohKarte;
    9. //...
    10. }
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ach du liebes lieschen, dass nenne ich mal mit dem Kopf durch die Wand.

    Ich habe ehrlich gesagt keine Ahnung wie ich dir da helfen soll, es sind so viele Dinge die mir hier ins Auge stechen, dass es echt schwierig ist da weiterzuhelfen.
    Aber ich kann dir sagen, dass "YugiohKarteErstellen" sehr isoliert ist.

    Wenn du dort eine neue Karte erstellst und sie als pointer an die zurückgegebene Karte zuweist, wird beim verlassen der Funktion die Karte aus dem Stack wieder entfernt.
    Da du nur den Pointer in pNext zurückgibst ist das auch sehr verständlich, du müsstest die neu erstellte Karte also entweder dynamisch am Heap erzeugen und dessen Addresse als pointer ablegen oder das neu erzeugte struct by value zurückgeben, und in einem Array, welches während des gesamten Programmablaufes besteht, abspeichern und in "main()" dann als pNext zur letzten Karte im Array übergeben.
    Derzeitiges Ergebnis liefert dir nur UB*, was nicht sehr zu empfehlen ist.

    Edit:
    *UB: Undefined Behaviour, heißt soviel wie keiner weiß was passieren wird, du begibst dich auf unbekannte Gefilde
    ----------------------------------------------------------------------------------------------------------------------

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

    ----------------------------------------------------------------------------------------------------------------------

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Elanda“ ()

    Ich weiss jetzt wie das geht.

    Ein Beispiel:

    C-Quellcode

    1. system("cls");
    2. printf("%10s %10s %10s\n", "Marke", "Km-Stand", "Jahrgang");
    3. for (struAuto* pOut = pStart; pOut != NULL; pOut = pOut->pNext)
    4. {
    5. printf("%10s %10i %10i\n", pOut->Marke, pOut->KmStand, pOut->Jahrgang);
    6. }