Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
000
26.10.2002, 09:24
voidi



hi.
ich bring mir grad c++ bei (versuche es) und stoße dabei auf folgendes problem:

Quellcode:
#include <iostream.h>
#include <conio.h>

void aendereSTR(char str[])
{
    if(str == "diesunddas") str = "dasunddies";
    else str = "blabla";
}

main()
{
char name[];

cout<<"enter name: ";
cin>>name;
name=aendereSTR(name);
cout<<name;
}

so das programm hab ich jetzt grade mal frei aus meinem gehirn abgetippt, da ich nicht an dem computer sitze wo ich programmiere.

ich compile also das ganze mit dem borland 5.5 c++ compiler und bekomme dann so ca. 5 fehlermeldungen,die mir irgend was komisches sagen mit "can not convert char to char *" oder so.
deshalb glaube ich dass ich da irgendwas mit zeigern machen muss, ich wüsste aber nicht wieso...

p.s. ich blicke in meinem buch nicht richtig durch und irgendwelche tuts haben mir bisher auch nucht geholfen. ich hoffe ihr könnt mir irgendwie helfen.

--

2far.net

<Teranite> ich hab nen arschmaessigen traffic

zum Seitenanfang zum Seitenende Profil || Suche
001
26.10.2002, 11:32
Mazze



Ja.
Also der Rückgabetyp von
Quellcode:void aendereSTR(char str[])
ist ja void.
Und du versuchst jetzt einem char* ein void zuzuweisen.
Das kann nicht gehen.

Du könntest jetzt ein char* zurückgeben, aber das macht man normal eh anders:
Quellcode:
#include <iostream.h>
#include <conio.h>

void aendereSTR(char *str)
{
    if(strcmp(str, "diesunddas") == 0)
        str = "dasunddies";
    
    else str = "blabla";
}

main()
{
    char name[];

    cout<<"enter name: ";
    cin>>name;
    aendereSTR(name);
    cout<<name;
}

So wird jetzt name direkt verändert, da ein Zeiger auf das Array übergeben wird. Ich weiß allerdings nicht wie weit du schon mit C/C++ bist und ob du schon weißt was das genau bedeutet.
2. Fehler:
Du kannst ein char array nicht einfach so vergleichen:
Quellcode:if(sz == "hallo")
Sondern du nimmst am besten die Funktion: strcmp(char*, char*); wenn die 0 zurückgibt sind die Strings gleich.

cu
Matze

--

BattleTech-MOD:
http://bthl.unitedgaming.net/

zum Seitenanfang zum Seitenende Profil || Suche
002
26.10.2002, 12:09
Tron



Quellcode:#include <iostream.h>

bei den standardheadern nicht mehr die .h version einbinden, das ist 'deprecated' (misbilligt) und wird irgendwann aus der sprache gestrichen, statt dessen:
#include <iostream>
und dann
using namespace std;
oder
statt z.b. cout => std::cout
stichwort: namespaces

Quellcode:#include <conio.h>
du verwendest keine funktionen daraus, also lass den header weg.

Quellcode:void aendereSTR(char str[])
{
  if(str == "diesunddas")
    str = "dasunddies";
  else
    str = "blabla";
}

das hat mazze schon geklaert, du vergleichst naemlich nicht den inhalt sondern die zeiger (also die position im speicher)

des weiteren schreibst du auch nicht in die strings sondern schreibst nur die adresse in die variable str, da aber str selbst eine wertuebergabe ist, wird in main nichts von dieser aenderung ankommen.

Quellcode:main()
so deklariert hat main zwar auch implizit den rueckgabewert int, aber man sollte es doch hinschreiben.
zudem sollte eine funktion, die den rueckgabewert int hat auch ein ein zurueckgeben, also ganz am ende ein return 0 und gut ist.

Quellcode:{
  char name[];

ein array braucht eine bekannte laenge

Quellcode:  cout << "enter name: ";
  cin >> name;

angenommen du deklarierst char name[10].
was passiert, wenn der benutzen einen namen mit 11 (eigentlicht rechen schon 10, wegen der terminierenden 0) eingibt?
richtig, katastrophe, da du dann in speicher schreibst, der nicht zu deinem array gehoert.
um dieses problem zu loesen, solltest du kein chararray verwenden, sondern z.b. einen strstream.

Quellcode:  name = aendereSTR(name);
das hat mazze geklaert

Quellcode:
  cout << name;
}

wie oben schon erwaehnt, ein return 0 am ende.

Zitat:
so das programm hab ich jetzt grade mal frei aus meinem gehirn abgetippt, da ich nicht an dem computer sitze wo ich programmiere.

ich denke mal, einige fehler, kamen durchs abtippen.

Zitat:
ich compile also das ganze mit dem borland 5.5 c++ compiler und bekomme dann so ca. 5 fehlermeldungen,die mir irgend was komisches sagen mit "can not convert char to char *" oder so.
deshalb glaube ich dass ich da irgendwas mit zeigern machen muss, ich wüsste aber nicht wieso...

bis man das thema zeiger ganz begriffen hat, dauert es ne weile...

Zitat:
p.s. ich blicke in meinem buch nicht richtig durch und irgendwelche tuts haben mir bisher auch nucht geholfen. ich hoffe ihr könnt mir irgendwie helfen.

wie heisst denn das buch?

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
003
26.10.2002, 13:30
voidi



Zitat:
Tron postete

Quellcode:#include <conio.h>
du verwendest keine funktionen daraus, also lass den header weg.

wie heisst denn das buch?

ich hatte die funktion getche() noch in meinem programm,deswegen die conio

das buch heisst c++ entpackt von herbert schildt

das ist eigentlich sehr gut und äußerst umfangreich aber nicht umbedingt ein einsteigerbuch, da es in einer sehr "hohen sprache" (imho) geschrieben ist.
und danke für die ermutigung, dachte schon ich wäre blöd :D

@mazze ich bin noch so ziemlich am anfang, aber deine erläuterung war verständlich, danke

ein paar fragen bleiben mir allerdings noch, ist das nun ein zeiger? "char*"

char ist ja ein datentyp und wann wird char nun als zeiger benutzt und wann nicht?
ich hab mir mal ein paar funktionen angeschaut, habe aber nicht begriffen wann man eine char var. als zeiger deklariert und wann nicht

--

2far.net

<Teranite> ich hab nen arschmaessigen traffic


Dieser Beitrag wurde am 26.10.2002 um 13:38 von voidi bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
004
26.10.2002, 22:27
Kriz



char* ist ein "Zeiger auf char". In C/C++ werden so Strings bezeichnet. Wenn man also schreibt:

char* s = "Hello world";

dann interpretiert der Compiler s erstmal so:

Hello world\0

Das abschließende Nullzeichen \0 ist das physische Ende des Strings, wird aber weder ausgegeben noch in einer Stringlängenberechnung verwendet. s zeigt als Zeiger auf den Speicherplatz des ersten Zeichens, hier 'H'. Wenn der String ausgegeben wird, dann geht das Programm ab der Adresse von 'H' solange je 1 Byte weiter (1 Byte = 1 Adresse pro Zeichen), bis das abschließende Nullzeichen erreicht wird. Dann ist die Ausgabe des Strings beendet.

--

K:R-I)Z++
"CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp
In memory of Voice († 2005/03/30)

zum Seitenanfang zum Seitenende Profil || Suche
005
28.10.2002, 15:54
CorDharel



Muss
Quellcode:str = "dasunddies");
nicht
Quellcode:strcpy(str,"dasunddies");
heissen?

--

Greetz CorDharel

Leader der HolyShitBastards


Dieser Beitrag wurde am 28.10.2002 um 15:59 von CorDharel bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
006
28.10.2002, 17:45
Kriz



Nicht unbedingt. Es kommt darauf an, inwiefern man "str" weiter benutzen will. Wenn "str" nun ein Zeiger auf char ist (char*), also ein String, dann ist die Zuweisung eines Stringliterals zulässig:
Quellcode:char* str = "Firlefanz";
"str" zeigt nun auf den ersten Buchstaben des Strings, also 'F'. Im Speicher sähe das dann so aus:
Quellcode:Index.: 0 1 2 3 4 5 6 7 8 9
String: F i r l e f a n z \0

Nun kannst du aber "str" wieder ein neues Stringliteral übergeben:
Quellcode:str = "ROFL";
Die Laufzeitumgebung ersetzt dann ab dem Index 0 den bisherigen String mit dem neuen String:
Quellcode:Index.: 0 1 2 3 4  5 6 7 8 9 10
String: R O F L \0 f a n z \0

Alles ab "fanz\0" ist dann offiziell wieder freigegeben von der Laufzeitumgebung. Man kann zwar noch auf "fanz" zugreifen, indem man etwas mit der Zeigerarithmetik des char* Datentyps spielt, aber sicher ist das nicht. Eventuell hat das Programm bereits wieder neue Daten dort abgelegt.

Du siehst, mit char* ist man variabel bei der Sache, weil im Prinzip nur mit Zeigerarithmetik gespielt wird. Die Funktion strcpy() ist auch hier möglich, macht aber im Prinzip nur das, was die Laufzeitumgebung intern auch macht (Überschreiben des Zielstrings).

Anders sieht die Sache mit einem Array von chars aus (char[]). Das ist zwar auch eine Art String, aber im weitesten Sinne eher doch ein Array von Zeichen. Da ein char-Array statisch ist (dynamische char-Arrays sind wiederum Zeiger auf char und daher vom Typ char* -> siehe oben), bekommt es einen festen Speicherbereich zugewiesen, der exakt n Elemente lang ist. Einem char-Array kann man auf zwei Arten ein Stringliteral zuweisen. Die erste Variante ist die Indexeinfügung, die zweite die Zeigerzuweisung.

Die Indexeinfügung sieht so aus:
Quellcode:char str[255]; // Ein char-Array mit 255 frei belegbaren Feldern
char* quelle = "Kokolores"; // Unser Stringliteral
int index = 0; // Index auf 0, bezeichnet also das erste Zeichen
while(quelle[index])
{
    str[index] = quelle[index];
    index++;
}

Der elegantere Weg führt über die Zeigerzuweisung:
Quellcode:char str[255]; // Ein char-Array mit 255 frei belegbaren Feldern
char* quelle = "Kokolores"; // Unser Stringliteral
char* temp = str; // Wir lassen temp auf str zeigen (wichtig!)
while(temp++ = quelle++);

temp zeigt auf das erste Feld von str und quelle auf das erste Zeichen seines Stringliterals. Nun wird das erste Zeichen von quelle nach temp kopiert. Danach werden die zeiger str und quelle inkrementiert. Zeigerinkremetierung bedeutet, daß ein Adressensprung von je 1 Byte durchgeführt wird (1 Byte ist die Speicherplatzmenge eines Zeichens). Nun zeigen also temp auf das zweite Feld und quelle auf das zweite Zeichen. Der Ergebnisausdruck der while()-Schleife ist solange "true", solange temp kein Nullzeichen empfängt. Das bedeutet, daß solange Zeichen für zeichen von quelle nach temp kopiert wird, bis temp das abschließende Nullzeichen vom quelle-Stringliteral erhalten hat. Dann bricht die Schleife ab und der Inhalt von quelle ist vollständig nach temp (bzw. str) kopiert worden. Das ist exakt die Arbeitsweise von strcpy()...

--

K:R-I)Z++
"CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp
In memory of Voice († 2005/03/30)

zum Seitenanfang zum Seitenende Profil || Suche
007
29.10.2002, 09:43
Hessie J.



Zitat:
Kriz postete
Nun kannst du aber "str" wieder ein neues Stringliteral übergeben:
Quellcode:str = "ROFL";
Die Laufzeitumgebung ersetzt dann ab dem Index 0 den bisherigen String mit dem neuen String:
Quellcode:Index.: 0 1 2 3 4  5 6 7 8 9 10
String: R O F L \0 f a n z \0

Alles ab "fanz\0" ist dann offiziell wieder freigegeben von der Laufzeitumgebung. Man kann zwar noch auf "fanz" zugreifen, indem man etwas mit der Zeigerarithmetik des char* Datentyps spielt, aber sicher ist das nicht. Eventuell hat das Programm bereits wieder neue Daten dort abgelegt.
.
.
.

Bidde? Gibt es echt eine 'Laufzeitumgebung', die so was macht?

Alle im Programm vorkommenden Stringliterale stehen doch irgendwo mehr oder weniger hintereinander (schreibgeschützt) im Speicher.

z.B. soQuellcode:Index..: 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E
Zeichen: F  i  r  l  e  f  a  n  z  \0 R  O  F  L  \0

Nach der ersten ZuweisungQuellcode:str = "Firlefanz";zeigt str auf Speicherindex 0, nach der zweiten ZuweisungQuellcode:str = "ROFL";zeigt str auf Speicherindex A.

--


Dieser Beitrag wurde am 29.10.2002 um 09:44 von Hessie J. bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
008
29.10.2002, 14:13
Tron



kriz, was du in #006 geschrieben hast ist groestensteils falsch, Hessie hat es korrekt dargelegt.

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche