Alles rund um Strings
-
CStoll schrieb:
Als Typ für die Längenangabe empfiehlt sich der Typ, den length() zurückgibt - size_t.
Aber ansonsten hat dein Programm noch ein kleines Problem - VLAs ("char c[l];") gibt es zwar in C99, aber nicht in C++.
Und was spricht dagegen, die Inhalte deines Strings direkt zu verwenden?
dann sieht das nun so aus:
#include <iostream> #include <string> using namespace std; int main() { string name = "yoda"; size_t l = name.length(); for(int i=0;i<l;++i) { char c = name[i]; cout << c << ' '; } cin.get(); }Wie mache ich das aber wenn ich den gesamten string in ein char- array speichern möchte?
das ich dann später wie folgt darauf zugreifen kann ( ausserhalb der Schleife, weil da überschreibt er ja nur immer den einen char namens c):
cout << c[0]; --> y
cout << c[1]; --> o
cout << c[2]; --> d
cout << c[3]; --> a
-
junger_padawan schrieb:
Wie mache ich das aber wenn ich den gesamten string in ein char- array speichern möchte?
Feste Größe für das Array angeben oder es auf dem Heap erzeugen - die Kopierschleife an sich ist in Ordnung (nur imho unnötig).
das ich dann später wie folgt darauf zugreifen kann ( ausserhalb der Schleife, weil da überschreibt er ja nur immer den einen char namens c):
Greif lieber direkt auf den String-Inhalt zu anstatt die Daten extra in ein char-Array zu kopieren (über name[0] bis name[3] kannst du die einzelnen Buchstaben abfragen).
-
So kannst du das ganze in einen c string kopieren, ist aber wiegesagt gar nicht nötig.
#include <string> #include <cstring> #include <iostream> using namespace std; int main() { string name = "yoda"; // Mit kopieren char* cname = new char[name.size() + 1]; strcpy(cname, name.c_str()); cout << cname[0] << '\n'; cout << cname[1] << '\n'; cout << cname[2] << '\n'; cout << cname[3] << '\n'; delete[] cname; // geht aber auch so direkt cout << name[0] << '\n'; cout << name[1] << '\n'; cout << name[2] << '\n'; cout << name[3] << '\n'; }
-
Okey dann also so:
string name = "yoda"; size_t l = name.length(); for(int i=0;i<l;++i) { cout << name[i] << ' '; }Was wäre aber jetzt wenn ich aus einer Datei einlesen will, es können max. 10 Zeilen stehen, und max. 50 Zeichen pro Zeile.
Ermitteln Sie für jede Zeile, wie viel Großbuchstaben (A – Z und Ä, Ö, Ü), wie viel Kleinbuchstaben (a – z, ä, ö, ü, ß) und wie viel sonstige Zeichen die Zeile enthält.
MEISTER Yoda weise, aber nicht weiß!! MEISTER obiwan PAdaWaN Skywalker Böser darthmaul !Wäre es dann auch sinnvoll nur mit string zu machen? oder eher mit char?
string datei = "c:\\daten.txt"; string line; ifstream in; in.open(datei.c_str()); getline(in,line);hier liest er ja nur die erste Zeile ein, wie mach ich das wenn ich die zweite Zeile im selben string haben möchte aber in neuer array zeile?
oder geht das nun nur mit c string?
-
Das geht mit C Strings genauso gut oder schlecht wie mit C++ Strings - du nimmst eine Schleife, um so lange zu lesen, bis deine Datei am Ende ist (mit C++ Strings geht es sogar noch besser, weil du keine Maximallänge für die Zeilen angeben mußt):
in.open(datei.c_str()); while(getline(in,line)) { //mach was mit der eingelesenen Zeile }(getline() liefert den Stream zurück - und der ist witzigerweise in einen Wahrheitswert konvertierbar, der aussagt, ob er noch Daten hat)
PS: Genau genommen hat der Stream einen operator void* - und dieser liefert den NULL-Zeiger zurück, wenn der Stream in einem Fehlerstatus (dazu gehört auch EOF) steckt. Und der NULL-Zeiger wird als Wahrheitswert false interpretiert und beendet die Lese-Schleife.
-
Was bringt die implizite Konvertierung nach void* ?
Außer das void* nach bool kovertierbar ist.
-
bonusfrage schrieb:
Was bringt die implizite Konvertierung nach void* ?
Außer das void* nach bool kovertierbar ist.Es erspart dir Schreibarbeit, weil du Anweisungen wie "if(cin)" oder das obige "while(getline(in,line))" schreiben kannst, ohne explizit auf .good() zu testen.
(und es bietet wunderbare Möglichkeiten, Neulinge zu verwirren :D)
-
also so dann? Leider kommt nach einem durchlauf der while schleife ein xstring fehler:
string subscript out of range
#include <iostream> #include <fstream> #include <string> #include <cstring> using namespace std; int main() { string datei = "c:\\daten.txt"; string line; ifstream in; in.open(datei.c_str()); int zeilen=0; while(getline(in,line)) { int g=0; int k=0; int sonstige=0; zeilen++; for (int i=0; i< 50; i++) { int ascii = line[i]; if (ascii == 153 || ascii == 152 || ascii == 142 || (ascii <=90 && ascii >= 65)) g+=1; if (ascii == 132 || ascii == 129 || ascii == 148 || (ascii <=122 && ascii >= 97)) k+=1; else sonstige+=1; } cout << "Zeile: " << zeilen << " hat " << g << " Grossbuchstaben und " << k << " Kleinbuchstaben und ausserdem " << sonstige << " andere Zeichen."<< endl; } cin.get(); }
-
Klar, die Zeilen haben ja teilweise auch weniger als 50 Zeichen - und da fliegt dir das Programm typischerweise um die Ohren (dein System scheint da recht fehlersicher zu sein). Ändere mal die Obergrenze der for()-Schleife auf den korrekten Wert
for(int i=0;i<line.length();++i)...
-
wenn in deiner Datei Zeilen mit weniger als 50 Zeichen stehen, wird getline entsprechend einen string einlesen, dessen Laenge weniger als 50 Zeichen betraegt. Dann jagst du in deiner for-schleife ueber das Ende des strings hinaus. (Uebrigens nett von deinem Compiler, in der debug-version so eine nette Fehlermeldung an Stelle eines simplen crash+core-dump hinzulegen >D) Deshalb:
for(int i=0; i< line.size(); ++i)/edit: CStoll mal wieder... antwortet schneller als die Polizei erlaubt

-
vielen dank jetzt funktioniert es tatellos

fals ich noch fragen zu strings habe werde ich sie hier posten.
Bis dahin machts gut.