# Frage zu C++ Anfängerprogramm



## JoergK (28. Januar 2012)

*Frage zu C++ Anfängerprogramm*

Hallo zusammen,
vor nun gut einer Woche habe ich damit begonnen, mir C++ Kenntnisse anzulesen und probiere Neues natürlich immer gleich in kleinen Testprogrammen aus. Allerdings tauchte heute ein (wahrscheinlich triviales) Problem auf, als ich erste Tests mit Zeigern machte.

Hier mein Programm: 

```
#include <cstdlib>
#include <cstdio>
#include <iostream>

using namespace std;

int main()
{
    char* testString;
    cout << "String angeben: ";
    cin >> testString;
    char a ;
    char b ;
    cout << "\nBuchstabe 1: ";
    cin >> a;
    cout << "\nBuchstabe 2: ";
    cin >> b;
    int abstand = 0;
    for (char* i = &testString; a=b; i++) {
        a = *i;
        abstand++;
    }
    cout << abstand;
    system("PAUSE");

    return 0;
}
```

Das ganze soll schlichtweg zunächst einen String und zwei Buchstaben einlesen und dann den Abstand zwischen den beiden Buchstaben ausgeben. Allerdings wirft der Compiler mir in der for-Schleifen Zeile einen Fehler aus, mit dem ich nichts anfangen kann:

```
error: cannot convert "char**" to "char*" in initialization
```
Ich werde wohl irgendwo was mit den Typen falsch deklariert haben - aber was ist <Typ>** ? Mir ist nur mit einem oder keinem Sternchen bekannt.

Vielleicht könnt ihr mir ja weiterhelfen 

Schönes Restwochenende noch !
Jörg


----------



## Crysis nerd (28. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

Ein Typ mit 2 Sternchen ist meines Wissens nach einfach ein Zeiger auf einen Zeiger, wie man vermuten kann. 
Du solltest das "&" vor dem "testString" in dem Schleifen Kopf wegnehmen.

Bei weiteren Fragen, schau im IRC Channel vorbei 
http://extreme.pcgameshardware.de/p...ign/199604-programmierer-irc-gruppenchat.html

mfg
Lukas


----------



## JoergK (28. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

Danke ! Startet jetzt. Tut zwar noch nicht das, was es soll, aber das bekomm ich schon gefixt. Danke.


----------



## mattinator (28. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

Du bist aber trotzdem noch etwas "verkehrt". Du deklarierst testString als Zeiger und liest eine Zeichenkette darauf ein, ohne ihm vorher Speicher zugewiesen zu haben. Da wäre z.B. char testString[256] besser, passt dann jedoch nur für max. 255 Zeichen (und das abschließende '\0'-Byte). Desweiteren setzt Du den Zeiger i auf die Adresse (!) des Zeigers testString (&-Operator) und erhältst somit nicht die einzelnen Zeichen auf *i bzw. a, sondern irgendwelche (zufälligen) Daten aus dem Stack.


----------



## JoergK (28. Januar 2012)

Danke erstmal. 
Aber wenn ich hinter Char testString noch [<Zahl>] setze, habe ich dann nicht einen Array of Char, statt eines Strings?


----------



## bingo88 (28. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

Ein string ist ein Array von chars 
Es gibt in C++ zwar auch den Datentyp string, der nutzt im Hintergrund aber eben ein solches Array.


----------



## JoergK (28. Januar 2012)

Aber ein Array ist nicht nullterminiert, oder ?
Ich dachte bei C++ wären Array of Char und String genauso verschieden, wie bspw. in Turbopascal. 
Dort ist es bspw. Verboten das Porgramm ein Array schreiben zu lassen ( write(testArray) geht nicht), da das Programm dann nicht die Auszugebende Stelle kennt. Mit write(testString) hätte es hingegen kein Problem. 

Wie deklariere ich in C++ denn dann einen Array of String, wenn Char Test ein String und Char Test [] ein Array of Char ist ?


----------



## bingo88 (28. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

Nullterminiert ist von Haus aus überhaupt nichts, dass musst in der Regel du als Programmierer machen.

Nehmen wir zum Beispiel folgenden Code:

```
char c[] = "Hallo!";
char *c = "Hallo"; // ist äquivalent zu char c[] = "Hello!";
```
Du gibst hier ja einen konstanten Text als Inhalt für das Char-Array an. Dein Compiler ergänzt in dieser Schreibweise automatisch das Nullzeichen und "stellt" auch genügen Speicher für den String bereit (daher brauchst du auch in den eckigen Klammern keine Arraygröße angeben!). Das ist jetzt allerdings etwas vereinfacht dargestellt ^^

Ein Array von Strings ist quasi ein Array von Arrays (char[][] bzw. char**). Wenn du C++ nutzt, solltest du aber besser auf den Datentyp std::string umstellen. Das ist eine Klasse, die ein char-Array kapselt und somit wesentlich einfacher zu verwenden ist.


----------



## mattinator (28. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

char ***Test ist nur / erst dann ein String, wenn bei der Deklaration ein String zugewiesen wird: char *Test="Das ist ein String"; Ansonsten ist es nur ein Zeiger !
In C werden alle Strings '\0'-terminated, das macht der Core von allein bei Operationen mit Strings. Damit wird das Ende des Strings markiert und alle String-Funktionen (strcmp, strcpy etc.) basieren darauf. C++ baut nur auf diesen Grundelementen auf und erweitert diese. Ein String ist immer mit einem Datenbereich in Länge des Strings + 1 verküpft, ein Zeiger ist nur ein Element, das Datenbereiche adressiert. In o.g. Deklaration wir ein Datenbereich im Code-Segment mit dem Inhalt "Das ist ein String\0" angelegt und der Zeiger Test mit dessen Anfang initialisiert. Die Deklaration char Test[19]="Das ist ein String" würde das selbe tun. In beiden Fällen würde der Compiler bei der Deklaration char Zeichen die Anweisung Zeichen=Test[0]; so um setzen, dass in Zeichen der Buchstabe 'D' steht. Mit der Deklaration char *Zeiger; und der Anweisung Zeiger=&Test[4]; oder Zeiger=Test+4; sollte nach Zeichen=*Zeiger; in Zeichen der Buchstabe 'i' stehen.

EDIT: Da war jemand schneller, das hier ist auch hauptsächliche die Sicht aus ANSI C. Mit C++ kann man das wirklich anders machen.


----------



## JoergK (28. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

Danke euch beiden. 
Ich glaube jetzt hab ich's dann auch verstanden. Mein Programm läuft jetzt nicht nur durch, sondern tut auch, was es soll.


```
#include <cstdlib>
#include <cstdio>
#include <iostream>

using namespace std;

char testString[256];

int buchstabenSuche (char buchs) {
    int i = 0 ;
    while (buchs != testString[i]) {
        i++;
    }
    return i;
}

int main()
{

    char a;
    char b;
    cout << "String eingeben: ";
    cin >> testString;
    cout << "A: ";
    cin >> a;
    cout << "B: ";
    cin >> b;
    int abstand;
    abstand = buchstabenSuche(b) - buchstabenSuche(a);
    cout << "Abstand: " << abstand  << "\n";
    system("PAUSE");
    return 0;
}
```

Aber ist es normal, dass ich der String bzw. das Array of Char keine Leerzeichen enthalten darf ? 
Bei einem zusammengeschriebenen Wort funktioniert alles, wie es soll, aber sobald Leerzeichen enthalten sind, werden weitere Eingaben übersprungen und unsinnige Werte ausgegeben.

Aber nochmal Danke euch beiden !!

Gruß Jörg


----------



## bingo88 (28. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

Nein, das liegt an dem cin. cin trennt nach Leerzeichen (genauer: Whitespaces). Versuch das mal mit

```
char str[1000];
cin.getline(str, 1000); // lies eine Zeile vom Standardeingabestream, max 999 Zeichen (+ Nullzeichen, also insgesamt 1000).
```


----------



## JoergK (29. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

Danke, daran hats gelegen !


----------



## bingo88 (29. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

kein Problem


----------



## mattinator (29. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

Eine kleine Korrektur noch, ansonsten läuft die Funktion  wenn Dein gesuchtes Zeichen nicht in der Zeichenketten enthalten ist solange durch die Stack-Daten, bis sie es woanders findet oder die Adresse in nicht zulässigen Bereichen liegt.



```
int buchstabenSuche (char buchs) {
    int i = 0 ;
    while (buchs != testString[i] && testString[i] != '\0') {
        i++;
    }
    return i;
}
```

Übrigens gibt es dafür die Funktion strchr. Aber ich denke, Dir ging es darum, das zum Lernen selbst abzubilden.


----------



## JoergK (29. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*

Ehrlich gesagt wusste ich das noch nicht 
Bisher haben sie in meinem Buch nur strlen, strcpy, strcat, strncmp und strstr und das ganze noch mit "n Zeichen" (z.B. strncpy) und ohne auf Groß- und Kleinschreibung zu achten (strnicmp).
Mit strstr hätte es doch aber auch funktioniert, wenn ich dem Programm den einzelnen Buchstaben als das gesuchte Pattern gegeben hätte, oder?


----------



## mattinator (29. Januar 2012)

*AW: Frage zu C++ Anfängerprogramm*



JoergK schrieb:


> Mit strstr hätte es doch aber auch funktioniert, wenn ich dem Programm den einzelnen Buchstaben als das gesuchte Pattern gegeben hätte, oder?


 
Bei strstr must Du als Suchparameter einen String angeben, also in Deiner Konstellation das eingelesene Zeichen als String speichern (z.B. mit sprintf). Da geht es mit strchr(char*,int) einfacher (strchr - C++ Reference). Wenn man in C++ programmieren kann, sollte man sich jedoch für die Klassen mit ihren Operatoren entscheiden, soweit diese verfügbar sind. Bei komplexen Programmen ist das i.d.R. von Vorteil. Kleinere Programme, gerade ohne grafische Oberfläche lassen sich jedoch auch sehr effizient mit ANSI C umsetzen. Ich habe damals C mit Kernighan / Ritchie gelernt (s.a. http://www.amazon.de/s/ref=nb_sb_ss_i_0_7?__mk_de_DE=%C5M%C5Z%D5%D1&url=search-alias%3Daps&field-keywords=kerningham+richie&x=0&y=0&sprefix=kerning%2Caps%2C271).


----------

