Zeiger kann nicht in Bool konvertiert werden

Hallo zusammen,
Meine erste Frage hier im Forum :)

Ich bekomme, wenn ich meine Programm kompiliere, folgenden Build Error:
D:\***\main.cpp In function `void split(std::string, std::string, std::string*)':
D:\***\main.cpp could not convert `*p' to `bool'

Hier die Splittfunktion bis zu besagter Fehlerstelle:
Code:
#include <string>
// [..]
using namespace std;
// [..]
void split(string seperator, string search, string* save) {
string* p = save;
// [..]
while(*p) {
// [..]

Das Argument save ist ein Array von Strings. Ich zeige mit p auf das erste Element.

Was ist da falsch?
Wieso kann ich denn nicht abfragen, ob der Zeiger noch gültig ist? In der Whileschleife wird er eben inkrementiert (p++) bis er hinter das Array zeigt. Muss ich da den string::iterator nehmen, oder was?

Gruss
jeko
 
Willkommen im Habo !

Ich zeige dir hier ein bsp wie du ein string array durchlaufen kannst.
Code:
#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

void echo(string* save,int size) 
{
     for(int i=0;i<size;i++)
     {
             cout<<save[i]<<endl;
             // das selbe mit zeigerschreibweise
             cout<<*(save+i)<<endl;
     }                
}

int main(int argc, char *argv[])
{
    const int SIZE=3;
    string array[SIZE] = {"Hello","Bla","dumm"};
    echo(array,SIZE);
    
    return 0;
}

Oft ist es sinnvoll gleich eine Länge des Arrays mitanzugeben. Das funktioniert gut weil ArrayLängen ohnehin konstant sein müssen.
Und das while(*p) kann bei dir nicht funktionieren weil * der Dereferenzierungsoperator ist und du an den String selber gelangst und das ist ja kein bool. Ich hoffe ich war dir eine Hilfe, aber du kannst ja fragen wenn du dich noch immer nicht auskennst.
 
Danke mauralix, ich würde jedoch gerne das Array vollständig mit dem Zeiger durchlaufen und keine Zählervariable verwenden.

Wie kann ich also überprüfen, ob der Zeiger schon zu weit ist? Es ist doch möglich, Arrays mit Zeigern zu durchlaufen, oder?
 
Zeiger auf string ist keine gute Idee; Nimm stattdessen vector; dann muss du auch die Größe nicht übergeben; Anonsten solltest du die Parameter als Referenz übergeben -> ist schneller :)

also

Code:
 split(string & seperator, string & search, vector<string> & save) {

EDIT: )

Das was du haben willst, geht nicht, weil es im string Array keine Abruchbedinung gibt; -> bei char Arrays ist es '\0'; (char != string; char speichert einzelnen Buchstaben; string speichert gesamten string; -> deshalb ist ein string Array was völlig anderes als ein char Array :) aber falls du selber eine Abruchbedingung einfügst, kannst du das Array so durchlaufen, wie du wolltest; z.B.

Code:
#include <vector>
#include <iostream>
#include <string>

using namespace std;

void print(string * s) {
	while(1) {
		if(*s == "END")
			break;
		cout << *s << endl;
		s++;
	}
}

int main(int argc, char *argv[])
{
	string *s = new string[4];
	s[0] = "Eins";
	s[1] = "Zwei";
	s[2] = "Drei";
	s[3] = "END";
	print(s);
}
 
Ok, in Anbetracht dessen, dass ich gerne etwas lernen möchte:

Wieso ist es nicht möglich mit einem Zeiger ein Feld von Strings zu durchlaufen???
 
Vielen Dank euch :)

Ich hab mal alle Tipps versucht umzusetzen und es ist jetzt fertig und funktioniert eigentlich ganz gut :)

Hier mal das Ergebnis:
Code:
void split(const string & seperator, const string & search, string* save, const int & save_length) {
// string search wird durch string seperator zerlegt; Bestandteile kommen in das Feld save;
// save_length ist die Grösse des Felds save
// Ist das Feld nicht gross genug, wird der Rest des Strings ins letzte Element gespeichert.

	string* p = save;
	string::size_type pos = 0;
	string::size_type nextpos = search.find(seperator,pos);
	const string::size_type len = search.length();
	for(int z = 0;z<save_length;z++) {
		*p = search.substr(pos,(nextpos-pos)); // Substr abspeichern
		pos = nextpos+1;
		nextpos = search.find(seperator,pos); // Nächstes Vorkommen suchen
		p++; // Array weitergehen
		if (nextpos == string::npos) break;
	}
	if (nextpos != string::npos) { // Arrayfehler
		p--; // zeigt auf letztes Element
		pos = pos - (*p).length() - 1; // pos zurücksetzen auf Position vor dem letzten Element
	}
	*p = search.substr(pos,(len-pos)+1); // Restl. String in letztes Element speichern
}
Beispielaufruf:
Code:
// Libs: string.h iostream.h, using namespace std
const int MAX_WORDS =3;
string* words = new string[MAX_WORDS];
string satz = "Hello World! This is foo bar!";

split(" ",satz,words,MAX_WORDS); // Trennt die Wörter

// Ausgeben
for (int i=0;i<MAX_WORDS;i++) cout << words[i] << "\n";
// Ergäbe ungefähr folgendes:
// Hello
// World!
// This is foo bar!

delete [] words;
Vll. kanns der eine oder andere ja mal brauchen :)
Das Beispiel ist ungetestet ^^
 
Schön das es nun geht.

den code kannst du vllt noch ein wenig verbessern. z.B *p.length() schreibt man eigentlich p->length(). Weiters musst du die Länge nicht als Referenz übergeben.
 
Also ich sehe keine Verbesserung in *p.length() zu p->length
Eine Verbesserung in meinem Sinne ist eine Optimierung, die mir in punkto Performance, Effizienz oder Design etwas bringt. Obenstehendes ist vll. dein persönlicher Stil?
 
Mhm...Eben :)

Und wieso die Länge nicht als Referenz übergeben? Schadets?

Ich dachte eben, weil Godfather oben meinte, Parameter als Referenz zu übergeben sei schneller.
 
Als Referenz übergeben lohnt sich nur bei Objekten und nicht bei sog. "primitiven" Datentypen wie int, da diese sowieso nur 4 Byte brauchen und es so eher schadet, ints als Referenz zu übergeben, da der Zeiger dann beim Zugriff erst wieder dereferenziert werden muss.
 
Zurück
Oben