Fehlersuche: Strings nach Trennzeichen aufteilen
-
Das sind Warnungen, keine Fehlermeldungen. Das Programm sollte also übersetzt sein. Verwende
std::size_t
stattìnt
für i und pos_ende, dann sollte es ohne Warnung übersetzen.
Wenn man ganz korrekt sein will, müsste esstd::string::size_type
sein, das aber in der Regel wieder nurstd::size_t
ist.
-
@duffy sagte in Fehlersuche: Strings nach Trennzeichen aufteilen:
"Ausnahme ausgelöst bei 0x7492DDC2 in Offline-06-01.exe: Microsoft C++-Ausnahme: std::out_of_range bei Speicherort 0x010BF49C.
Unbehandelte Ausnahme bei 0x7492DDC2 in Offline-06-01.exe: Microsoft C++-Ausnahme: std::out_of_range bei Speicherort 0x010BF49C."Ist ja eigentlich ganz simpel. Du hast eine Ausnahme bei 0x7492DDC2 in dem Programm Offline-06-01.exe ausgelöst und zwar einen out_of_range Fehler am Speicherort 0x010BF49C. Den hast du dann auch nicht behandelt. Was an diesen Stellen im Speicher genau steht, kannst du sehr simpel mit einem Debugger nachschauen. Dann dürfte dir eigentlich sofort klar sein, was da schief geht.
-
@swordfish sagte in Fehlersuche: Strings nach Trennzeichen aufteilen:
pos_ende
und die diverseni
s sollten vom Typ std::size_t sein. Das ist auch, was zBstd::string::length()
zurückgibt.Geht da nicht auch einfach unsigned int? Laut Internet ist size_t doch auch ein Typ von unsigned int...
@manni66 sagte in Fehlersuche: Strings nach Trennzeichen aufteilen:
Das sind Warnungen, keine Fehlermeldungen. Das Programm sollte also übersetzt sein. Verwende
std::size_t
stattìnt
für i und pos_ende, dann sollte es ohne Warnung übersetzen.
Wenn man ganz korrekt sein will, müsste esstd::string::size_type
sein, das aber in der Regel wieder nurstd::size_t
ist.Gleiches wie oben.
Hat sich bereits erledigt. Das Programm hat nicht kompiliert weil ich eine andersnamige .cpp Datei im Quellordner hatte welche die gleiche Funktion definiert hatte aber mit anderen Inhalten. Diese war zwar nicht eingebunden aber hat wohl irgendwie Probleme verursacht...
Das Programm läuft jetzt auch mit den int-Werten Problemlos aber ich werd mich aufjedenfall mal mit den Alternativen auseinander setzen...
Vielen Dank an alle für die tolle Hilfe!
War bestimmt nicht mein letztes mal. :face_savouring_delicious_food:
-
@tggc sagte in Fehlersuche: Strings nach Trennzeichen aufteilen:
@duffy sagte in Fehlersuche: Strings nach Trennzeichen aufteilen:
"Ausnahme ausgelöst bei 0x7492DDC2 in Offline-06-01.exe: Microsoft C++-Ausnahme: std::out_of_range bei Speicherort 0x010BF49C.
Unbehandelte Ausnahme bei 0x7492DDC2 in Offline-06-01.exe: Microsoft C++-Ausnahme: std::out_of_range bei Speicherort 0x010BF49C."Ist ja eigentlich ganz simpel. Du hast eine Ausnahme bei 0x7492DDC2 in dem Programm Offline-06-01.exe ausgelöst und zwar einen out_of_range Fehler am Speicherort 0x010BF49C. Den hast du dann auch nicht behandelt. Was an diesen Stellen im Speicher genau steht, kannst du sehr simpel mit einem Debugger nachschauen. Dann dürfte dir eigentlich sofort klar sein, was da schief geht.
Habe ich im Debugger durchlaufen lassen. Diese Fehlermeldung kam dann an exakt dieser Stelle ohne weitere Meldungen. Ich weiß ja mittlerweile, dass ich nicht auf die Positionen im String zugreifen konnte weil der String leer war.
Ärgere mich, dass ich da nicht selber draugekommen bin... manchmal sieht man den Wald vor lauter Bäumen nicht und mir fehlt da wohl noch die Routine.
-
@duffy sagte in Fehlersuche: Strings nach Trennzeichen aufteilen:
Geht da nicht auch einfach unsigned int? Laut Internet ist size_t doch auch ein Typ von unsigned int...
Wenn irgendwo steht,
std::size_t
sei einunsigned int
dann ist das falsch. Ich gehe aber davon aus, daß Du unsigned integer gelesen hast und Dein Kopf daraus automagischunsigned int
gemacht hat. Gemeint ist irgendein vorzeichenloser, ganzzahliger Typ, der groß genug für alle Objekte ist, die im Speicher rumliegen können. Oft wird es wohl einstd::uint64_t
sein.§21.2.4 (3):
The type size_t is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object.
Ähnlich wie von @spiri vorgeschlagen wäre meine Antwort auf die Aufgabenstellung aber
bool teilen(char trennzeichen, std::string const & eingabe, std::string & erster_teil, std::string & zweiter_teil) { auto trennzeichen_position{ eingabe.find(trennzeichen) }; if (trennzeichen_position == eingabe.npos) return false; erster_teil = std::string{ eingabe.begin(), eingabe.begin() + trennzeichen_position }; zweiter_teil = std::string{ eingabe.begin() + trennzeichen_position + 1, eingabe.end() }; return true; }
-
@swordfish Erwischt^^
Ich mach mich da nochmal schlau... Danke!
-
Ich finde die Sonderfallbehandlung bei @swordfish nicht intuitiv. Wenn kein Trennzeichen vorhanden, ändere die Ausgabestrings nicht? Wie soll dann der Aufrufer ermitteln, ob die beiden Ausgabestrings korrekt gesetzt sind oder unverändert geblieben sind? Daher würde ich eher so vorgehen, dass ich in diesem Fall ersterTeil=eingabe, zweiterTeil="" setzen würde.
Wobei allgemein die Frage auch ist, ob man nicht eher einfach ein
pair<string(_view), string(_view)>
zurückgeben sollte. Und natürlich den eingabestring als const-ref nehmen! 4 Pflicht-Parameter sind schon ganz schön viel! Zu _sv: bin mir nicht so sicher, sollte man das tun? Was ist, wenn jemand die Funktion mit einem Temporary aufruft?
-
@wob sagte in Fehlersuche: Strings nach Trennzeichen aufteilen:
Ich finde die Sonderfallbehandlung bei @swordfish nicht intuitiv. Wenn kein Trennzeichen vorhanden, ändere die Ausgabestrings nicht? Wie soll dann der Aufrufer ermitteln, ob die beiden Ausgabestrings korrekt gesetzt sind oder unverändert geblieben sind? Daher würde ich eher so vorgehen, dass ich in diesem Fall ersterTeil=eingabe, zweiterTeil="" setzen würde.
Dann müsste der Aufrufer
ersterTeil == eingabe
prüfen um herauszufinden, ob das Trennzeichen in dereingabe
enthalten ist, oder nicht. Ich würde einfach einenbool
zurückgeben. Edited.@wob sagte in Fehlersuche: Strings nach Trennzeichen aufteilen:
Wobei allgemein die Frage auch ist, ob man nicht eher einfach ein
pair<string(_view), string(_view)>
zurückgeben sollte. [...] Zustring_view
: bin mir nicht so sicher, sollte man das tun? Was ist, wenn jemand die Funktion mit einem Temporary aufruft?Dann ist der
string_view
schneller kaput als du "hopp" sagen kannst
-
Es war leider explizit in der Aufgabenstellung aus den Unterlagen gefordert, dass die Funktion folgende Form hat:
void spalte_ab_erstem(char zeichen, string eingabe, string& erster_teil, string& zweiter_teil)
Der Code wird später noch für 1-2 aufbauende Aufgabenstellung verwendet, weswegen ich mich an die Vorgaben halten wollte (wer weiß was da noch kommt o.O).
Dennoch ist es nett zu sehen wie du es gelöst hättest mit bool... Danke hierfür!
Kann nie schaden auch mal andere herangehensweisen zu betrachten.
-
Dann poste ich auch mal meine Lösung.
Ganz einfach gehalten:#include <string> #include <utility> std::pair<std::string, std::string> teilen(const std::string& s, char delim){ std::size_t pos = s.find(delim); if(pos == std::string::npos) return {s, ""}; return {s.substr(0, pos), s.substr(pos + 1)}; }
-
@spiri sagte in Fehlersuche: Strings nach Trennzeichen aufteilen:
Ganz einfach gehalten:
// ...
Noch einfacher gehalten:
#include <string> #include <utility> std::pair<std::string, std::string> teilen(std::string const & s, char delim) { auto pos{ s.find(delim) }; return { s.substr(0, pos), s.substr(pos + 1) }; }
-
Klar, damit erzeugst du nen Überlauf.
-
substr()
wirftout_of_range
nurif pos
[1]> size()
. Im Fallepos == npos == -1
undpos + 1
ist das Ergebnis0
, was nie> size()
sein kann. --> wirft nicht.
Produziert halt auch in.second
vompair
den Eingabestring.[1]
pos
... erster Parameter vonsubstr()
.
-
@duffy sagte in Fehlersuche: Strings nach Trennzeichen aufteilen:
Habe ich im Debugger durchlaufen lassen. Diese Fehlermeldung kam dann an exakt dieser Stelle ohne weitere Meldungen.
Dann lerne bitte auch mit dem Debugger umzugehen. Der zeigt da natürlich noch viel mehr an, dass einfach nur diese Meldung kommt ist gelogen. So eine Exception passiert nicht aus dem nichts, sondern man kann sehr genau nachvollziehen aus welcher Vorbedingung sie aktuell folgt. Da würde man genau sehen, das der übergebene Index >= size war. Das wird dir noch sehr oft passieren also wirst du mit Programmieren nicht weit kommen, wenn dir so grundsätzliche Kenntnisse fehlen. In dem Fall hätte man es ausserdem auch in der Doku nachlesen können, da die Exception ja aus der Systembibliothek kam.