Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

23.06.2014, 17:47

C++ inhalt von char-Array an Variable übergeben und wieder zurück

Tach

Unternehme gerade meine ersten Schritte im C++ Programmieren und bin natürlich prompt auf ein Problem gestossen ;)

Ich habe zur Übung ein kleines Konsolen-Programm geschrieben mittels dem man in einem zweidimensionalen Koordinatensystem den einzelnen Felder verschiedene Werte zuweisen kann. Funktioniert so weit auch so wie es soll. Nun wollte ich es um eine Funktion erweitern mittels derer man die Werte welche man für ein Feld eingegeben hat auf ein anderes Feld überschreiben kann in dem man einfach erst die Koordinaten des Ausgangsfeldes und dann die Koordinaten des Zielfeldes eingibt. So weit funktioniert auch das, bis auf eine Einschränkung.

Die Daten bestehen einerseits aus diversen Integer-Werten, aber auch aus einem char-Array. Nun hatte ich keine grossen Probleme damit die Integer auszulesen und an das neue Feld zu übergeben, mit dem char-Array jedoch komme ich nicht weiter. Mit den Integer-Werten habe ich das so gelöst dass ich die Zahlen nach Eingabe der Ursprungskoordinaten in eine lokale Variablen auslese und dann nach Eingabe der Zielkoordinaten von diesen lokalen Variablen wieder übergebe. Die Daten auf den alten Koordinaten werden danach gelöscht. Mit dem char-Array funktioniert das mit den mir bisher bekannten Befehlen und Operatoren jedoch nicht.

Ausgangslage:

Ich habe ein variables char Array mit max. 10 Zeichen innerhalb einer Struktur in welches ein Wert eingetragen und bestimmten Koordinaten in einem zweidimensionalen Array zugeordnet wurde.

Gewünschter Programmablauf:

Ich will nun den im char-Array enthaltenen Text unter Angabe der Koordinaten auslesen und wieder übergeben. Wie funktioniert das?

Nachfolgend mal die relevanten Abschnitte aus dem Quellcode. Wundert Euch nicht über die Begriffe. Da ich als Logistiker arbeite erschien es mir naheliegend zur Übung ein kleines Lagerverwaltungsprogramm zu schreiben ;)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
struct S_Lagerplatz
{
    bool Besetzt;
    int Artikel;
    int Menge;
    char ME[10];
};

const int Platz = 6;
const int Ebene = 3;

S_Lagerplatz Regal[Platz][Ebene];


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
            cout << "Lagerplatz eingeben: ";
            cin >> x;

            cout << "Lagerebene eingeben: ";
            cin >> y;

            // Daten aus Bestand an lokale Variablen übergeben
            Artikel = Regal[x][y].Artikel;
            Menge = Regal[x][y].Menge;

            // Lagerplatz ändern
            cout << "Neuen Platz eingeben: ";
            cin >> x;

            cout << "Neue Ebene eingeben: ";
            cin >> y;
            
            // Daten an neuen Lagerplatz übergeben
            Regal[x][y].Artikel = Artikel;
            Regal[x][y].Menge = Menge;

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

23.06.2014, 17:56

Willkommen im Forum!

Du kannst ein Array nicht einfach einem anderen Array zuweisen. Das ist eines der Probleme damit.
Lieber solltest du die std::string-Klasse verwenden, um Zeichenfolgen zu speichern.
Wenn es unbedingt Arrays sein müssen, dann musst du jedes Element einzeln von Array A nach Array B kopieren (for-Schleife) oder eine Funktion wie memcpy bzw. strcpy benutzen.
Ich empfehle aber ganz klar std::string.

3

24.06.2014, 09:41

Nun, das Array habe ich deshalb gewählt weil es Teil von dem ist was ich momentan üben muss (und weil ich die anderen Möglichkeiten noch gar nicht kenne). Aber wenn's nicht geht dann geht's nicht ;)

Ich versuch's dann mal mit std::string und schau ob ich's damit wie gewünscht hinkriege.

Danke

4

24.06.2014, 23:36

Nochmal die ausführliche Erklärung (for beginners), wie es mit den char-Arrays ist:

Ein char-Array ist nichts weiter, als ein Speicherbereich mit n-Bytes. n ist dabei gleichzeitig die Länge der Zeichenkette (String).
In der Variable ME speicherst du jetzt nur einen Pointer (Zeiger) auf diesen Speicherbereich. Dieser Pointer stellt also eine Adresse der ersten Speicherzelle des Speicherbereiches dar.
Natürlich könntest du diesen jetzt einfach überschreiben und auf einen anderen Speicherbereich zeigen lassen, aber dann ist der ehemalige Zeiger verloren und niemand weiß mehr, wo der ehemalige Speicherbereich lag.

Du könntest also entweder die Adressen austauschen, oder, da beide Zeichenketten eine feste Länge von 10 bei dir haben, die Daten der Speicherbereiche austauschen (wie David schon schrieb mit memcpy bspw.)

Für nähere Informationen bin ich sicher, dass auch irgendwo im Internet gute Tutorials rumschwirren ;)
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

25.06.2014, 06:44

Ein char-Array ist nichts weiter, als ein Speicherbereich mit n-Bytes. n ist dabei gleichzeitig die Länge der Zeichenkette (String).
Das stimmt so nicht ganz, bzw. könnte falsch verstanden werden. "foobar" hat zwar nur 6 chars, der Speicherbereich dafür ist aber 7 Bytes lang, weil am Ende ein 0-Byte als Markierung für das Ende des Strings steht. Das heißt umgekehrt auch, dass ein char[10] nur einen String mit 9 Zeichen Länge aufnehmen kann. Man könnte zwar auch 10 reinpacken, aber dann arbeiten cout, strcpy und weitere Funktionen nicht mehr korrekt.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

6

25.06.2014, 09:34

Etwas unglücklich formuliert, ja.

Nur string literals werden null-terminated. Ein char Array mit folgender Deklaration ist immernoch 5 Bytes lang:

C-/C++-Quelltext

1
char x[5];


Folgendes char-Array belegt hingegen 6 bytes:

C-/C++-Quelltext

1
char x[] = "abcde";
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »iSmokiieZz« (25.06.2014, 09:42)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

25.06.2014, 10:54

Klar, aber du kannst eben kein "fuenf" einem char[5] korrekt zuweisen (eben auch nicht per memcpy oder strcpy) und es weiterhin als String benutzen (für strcmp oder cout), eben weil die abschließende 0 dann fehlt oder die Größe inkompatibel ist.
Unter anderem wegen lauter solchem Unfug ist std::string eben deutlich besser.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

8

25.06.2014, 16:35

Puh, geschafft! :)

Unten mal der entsprechende Code-Auszug. Vermutlich gäbe es auch elegantere Lösungen für das ganze, aber das kommt dann mit der Zeit ;)

Danke erst mal. Ich werde sicher schon bald mit dem nächsten Problem zurück sein :D

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
            cout << "Lagerplatz eingeben: ";
            cin >> x;

            cout << "Lagerebene eingeben: ";
            cin >> y;

            // Daten aus Bestand an lokale Variablen übergeben
            Artikel = Regal[x][y].Artikel;
            Menge = Regal[x][y].Menge;
            strcpy(ME, Regal[x][y].ME);

            // Alten Platz als frei markieren
            Regal[x][y].Besetzt = false;

            // Lagerplatz ändern
            cout << "Neuen Platz eingeben: ";
            cin >> x;

            cout << "Neue Ebene eingeben: ";
            cin >> y;
            
            // Daten an neuen Lagerplatz übergeben
            Regal[x][y].Artikel = Artikel;
            Regal[x][y].Menge = Menge;
            strcpy(Regal[x][y].ME, ME);

9

26.06.2014, 12:32

Und da bin ich auch schon wieder ;)

So weit funktioniert jetzt alles so wie es sollte, nur ein klitzekleines Problemchen hab' ich noch:

Ich sagte ja schon dass die Daten auf dem ursprünglichen Feld gelöscht werden nachdem sie auf das neue Feld geschrieben wurden. Für die Integer-Werte habe ich das jetzt mal so gelöst dass die einfach alle auf 0 gesetzt werden was mir nach ein wenig googeln zu dem Thema als eine gute Lösung erscheint. Nur das char-Array macht natürlich mal wieder Probleme, denn das kann ich ja nicht einfach auf 0 setzen da es sich um Text und nicht um eine Zahl handelt.

Die Frage ist also: Wie lösche ich diesen Text?

Im Netz habe ich zu dem Thema zwar diverses gefunden, aber das meiste davon übersteigt meine momentanen Fähigkeiten und der Rest hat bei rumprobieren nicht funktioniert.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

10

26.06.2014, 12:37

Wozu löschen?
Du hast doch das Feld Besetzt, um dir anzuzeigen, ob das Feld frei (= gelöscht) oder belegt ist.

Werbeanzeige