 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Andreas Volz Guest
|
Posted: Sat Jun 12, 2004 12:45 pm Post subject: string einlesen? |
|
|
Hi,
ich habe das versucht um einen String in C++ einzulesen.
std::string parser_string;
std::cin >> parser_string;
Jedoch bekomme ich bei Strings mit Leerzeichen immer nur den letzten
Teilstring eingelesen. Muss ich also erst ein char-Array mit fgets()
einlesen und dann erst ein C++ string daraus machen, oder geht das auch
direkt mit cin?
Gruß
Andreas
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Sat Jun 12, 2004 2:23 pm Post subject: Re: string einlesen? |
|
|
Andreas Volz wrote:
| Quote: | Hi,
ich habe das versucht um einen String in C++ einzulesen.
std::string parser_string;
std::cin >> parser_string;
Jedoch bekomme ich bei Strings mit Leerzeichen immer nur den letzten
Teilstring eingelesen.
|
Den letzten?
| Quote: | Muss ich also erst ein char-Array mit fgets()
einlesen und dann erst ein C++ string daraus machen, oder geht das
auch direkt mit cin?
|
Bis wo willst du denn genau lesen? operator>> liest bis zum nächsten
Whitespace. Wenn du eine Zeile einlesen willst, nimm std::getline.
std::getline(cin, parser_string);
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Wolfgang Kaufmann Guest
|
Posted: Sat Jun 12, 2004 4:15 pm Post subject: Re: string einlesen? |
|
|
* Thus spoke Andreas Volz <usenet-spam-trap (AT) brachttal (DOT) net>:
Hallo,
| Quote: | std::cin >> parser_string;
Jedoch bekomme ich bei Strings mit Leerzeichen immer nur den letzten
Teilstring eingelesen.
|
Du meinst den ersten, richtig?
| Quote: | Muss ich also erst ein char-Array mit fgets() einlesen und dann erst
ein C++ string daraus machen, oder geht das auch direkt mit cin?
|
Nein, dazu dafür gibts getline, siehe z. B.
| Quote: | #include
#include
int main() {
std::string line;
while(getline(std::cin, line)) {
std::cout << line << std::endl;
}
}
|
Wolfgang.
--
"If you've a highlighter pen, these lines above have got to be marked."
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Ralph Oliver Schunk Guest
|
Posted: Mon Jun 14, 2004 1:43 pm Post subject: Re: string einlesen? |
|
|
Andreas Volz <usenet-spam-trap (AT) brachttal (DOT) net> wrote:
| Quote: | Hi,
ich habe das versucht um einen String in C++ einzulesen.
|
Hallo Andreas,
du hast wahrscheinlich irgend etwas in der Art:
std::string
get_string()
{
std::string parser_string;
while ( std::cin >> parser_string )
{
//...
}
return parser_string;
}
geschrieben. Oder?
Sonst kapier' ich denn nächsten Satz nicht ;o) .
| Quote: | Jedoch bekomme ich bei Strings mit Leerzeichen immer nur den letzten
Teilstring eingelesen.
|
std::cin liesst immer nur bis zum nächsten Leerzeichen.
Ein String mit mehreren Leerzeichen liest Du dann besser so ein:
std::string
get_string()
{
std::string cur_item;
std::string parser_string;
const std::string delimiter( " " );
while ( std::cin >> cur_item )
{
parser_string += cur_item + delimiter;
}
return
parser_string.substr( 0, parser_string.size() - delimiter.size() ) ;
}
Die Lösung mit getline ist mutmasslich schneller,
versagt aber bei Eingabeumleitung.
Mit Referenzen könnte man sich auch noch das
Kopieren der Strings sparen.
Gruß
Ralph
--
Es gibt 10 Arten von Menschen,
die, die Binär lesen können,
und die, die es nicht können.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Babak Pourat Guest
|
Posted: Mon Jun 14, 2004 2:51 pm Post subject: Re: string einlesen? |
|
|
Andreas Volz wrote:
| Quote: | ich habe das versucht um einen String in C++ einzulesen.
std::string parser_string;
std::cin >> parser_string;
Jedoch bekomme ich bei Strings mit Leerzeichen immer nur den letzten
Teilstring eingelesen. Muss ich also erst ein char-Array mit fgets()
einlesen und dann erst ein C++ string daraus machen, oder geht das
auch direkt mit cin?
|
Natürlich gehts auch mit cin und zwar mit hilfe eines speziellen facets:
(quelle: Tom Usenet / microsoft.public.vc.stl)
#include <locale>
#include <string>
class space_ctype: public std::ctype<char>
{
public:
space_ctype(std::string const&
whitespaces):std::ctype<char>(get_mask(whitespaces), true) {
};
private:
static mask const* get_mask(std::string const& whitespaces)
{
mask* m = new mask[table_size];
mask const* classic =std::ctype<char>::classic_table();
for (size_t j = 0; j < table_size; ++j){
m[j] = (mask)(classic[j] & ~space);
}
for(std::string::const_iterator i = whitespaces.begin(), end =
whitespaces.end(); i != end; ++i){
m[static_cast
char>(*i)] | space);
}
return m;
}
};
static std::locale loc_space(std::locale("C"), new space_ctype("")); // kein
space zeichen!
std::cin.imbue(loc_space);
std::string parser_string;
std::cin >> parser_string;
Wenn man die ganze Klassen deklaration von "space_ctype" in ein H-File
auslagert dann ist das ganze auch nicht mehr so unhandlich!
Gruss Babak
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Edzard Egberts Guest
|
Posted: Mon Jun 14, 2004 8:34 pm Post subject: Re: string einlesen? |
|
|
Hallo,
| Quote: | | while(getline(std::cin, line)) {
| std::cout << line << std::endl;
|
man kann aber auch nullterminierte Strings lesen und schreiben, die dann
auch Linefeed enthalten können (open binary):
//----------------------------------------------------------------------------
void rd_str(istream& In, string& Str)
{
std::getline(In, Str, ' ');
}
//----------------------------------------------------------------------------
void wr_str(ostream& Out, const string& Str)
{
Out << Str << std::ends;
}
Gruß,
Ed
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Jun 15, 2004 8:52 am Post subject: Re: string einlesen? |
|
|
"Babak Pourat" <pourat (AT) autronic (DOT) melchers.de> wrote
| Quote: | Andreas Volz wrote:
ich habe das versucht um einen String in C++ einzulesen.
std::string parser_string;
std::cin >> parser_string;
Jedoch bekomme ich bei Strings mit Leerzeichen immer nur den letzten
Teilstring eingelesen. Muss ich also erst ein char-Array mit fgets()
einlesen und dann erst ein C++ string daraus machen, oder geht das
auch direkt mit cin?
Natürlich gehts auch mit cin und zwar mit hilfe eines speziellen
facets: (quelle: Tom Usenet / microsoft.public.vc.stl)
|
Das scheint mir einen bedeutenden Mißbrauch von Facets. Dazu muss man
damit äußerst vorsichtig angehen.
| Quote: | #include <locale
#include
class space_ctype: public std::ctype
{
public:
space_ctype(std::string const&
whitespaces):std::ctype
};
private:
static mask const* get_mask(std::string const& whitespaces)
{
mask* m = new mask[table_size];
mask const* classic =std::ctype<char>::classic_table();
for (size_t j = 0; j < table_size; ++j){
m[j] = (mask)(classic[j] & ~space);
}
for(std::string::const_iterator i = whitespaces.begin(), end =
whitespaces.end(); i != end; ++i){
m[static_cast
char>(*i)] | space);
}
return m;
}
};
static std::locale loc_space(std::locale("C"), new space_ctype("")); // kein
space zeichen!
std::cin.imbue(loc_space);
|
Da hast du auch alle andere Facets des Stroms geändert. Normallerweise
macht man höchst:
std::cin.imbue( std::locale( std::cin.getloc(), new space_ctype( "" ) ) ) ;
Nur würde ich nie die Semantik vom ctype Facet ändern, weil es vom z.B.
std::num_get benutzt wird.
| Quote: | std::string parser_string;
std::cin >> parser_string;
Wenn man die ganze Klassen deklaration von "space_ctype" in ein H-File
auslagert dann ist das ganze auch nicht mehr so unhandlich!
|
In Allgemein: die Norm gibt dem ctype-Facet eine ganz genaue Semantik.
Deine Instanzierungen sollen an diese Semantik halten.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Babak Pourat Guest
|
Posted: Tue Jun 15, 2004 10:50 am Post subject: Re: string einlesen? |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
| Quote: | Natürlich gehts auch mit cin und zwar mit hilfe eines speziellen
facets: (quelle: Tom Usenet / microsoft.public.vc.stl)
Das scheint mir einen bedeutenden Mißbrauch von Facets.
|
Sehe ich nicht so. Die Facets sind dafür da um damit zu arbeiten.
Wo siehst du die Anwendung dafür dass es im Konstruktor vom ctype(const
mask*,...)
die Variable vom type "mask" gibt an mit was "space" oder "upper" ist. Und
wenn meine Vorstellung von space etwas anderes ist als die standard
Einstellung, dann teile ich es ihm auf diese Art mit.
| Quote: | Dazu muss man damit äußerst vorsichtig angehen.
Durch aus, vor allem deshalb weil man (zumindes Ich) einige Zeit braucht um |
durch zu steigen
| Quote: | static std::locale loc_space(std::locale("C"), new space_ctype(""));
// kein space zeichen!
std::cin.imbue(loc_space);
Da hast du auch alle andere Facets des Stroms geändert. Normallerweise
macht man höchst:
std::cin.imbue( std::locale( std::cin.getloc(), new space_ctype(
"" ) ) ) ;
|
Sehe ich ein.
| Quote: |
Nur würde ich nie die Semantik vom ctype Facet ändern, weil es vom
z.B. std::num_get benutzt wird.
|
Natürlich erhebe ich nicht den Anspruch der Fehler freiheit. Aber ich habe
aus diesem Beispiel einiges gelernt.
| Quote: |
In Allgemein: die Norm gibt dem ctype-Facet eine ganz genaue Semantik.
Deine Instanzierungen sollen an diese Semantik halten.
|
Ja
Babak
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Fri Jun 18, 2004 9:11 pm Post subject: Re: string einlesen? |
|
|
"Babak Pourat" <pourat (AT) autronic (DOT) melchers.de> writes:
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote:
Natürlich gehts auch mit cin und zwar mit hilfe eines speziellen
facets: (quelle: Tom Usenet / microsoft.public.vc.stl)
Das scheint mir einen bedeutenden Mißbrauch von Facets.
Sehe ich nicht so. Die Facets sind dafür da um damit zu arbeiten. Wo
siehst du die Anwendung dafür dass es im Konstruktor vom ctype(const
mask*,...)
|
Es geht um Lesbarkeit. Facets sind in allgemein eine sehr schwere und
relatif wenig verstandene Mittel, einen Strom an eine Codierung und eine
Gegend anzupassen. Ich finde sie für das alltägliches Parsen schwer,
unübersichtlich, und nicht besonders lesbar. Wenn ich einen operator>>
nach einer Kette sehe, erwarte ich, dass ein durch Leerzeichen
getrenntes Wort gelesen wird. Man kann die Semantik umbiegen, aber am
Ende, was habe ich -- ich weiß nicht mehr, was operator>> tut.
Dagegen, wenn ich eine richtige genannte Funktion benutze, ist alles
klar.
Wenn ich Locale sehe, erwarte ich auf eine allgemeine Anpassung des
Stromes auf eine andere Cndierung oder eine andere Gegend.
| Quote: | die Variable vom type "mask" gibt an mit was "space" oder "upper"
ist. Und wenn meine Vorstellung von space etwas anderes ist als die
standard Einstellung, dann teile ich es ihm auf diese Art mit.
Dazu muss man damit äußerst vorsichtig angehen.
Durch aus, vor allem deshalb weil man (zumindes Ich) einige Zeit
braucht um durch zu steigen
|
Und wie. Dazu sind sie nicht von allen Compilern besonders gut
unterstützt; das letzte Mal, dass ich die mit g++ ausprobiert habe, sind
die überhaupt nicht gegangen.
| Quote: | static std::locale loc_space(std::locale("C"), new space_ctype(""));
// kein space zeichen!
std::cin.imbue(loc_space);
Da hast du auch alle andere Facets des Stroms geändert.
Normallerweise macht man höchst:
std::cin.imbue( std::locale( std::cin.getloc(), new space_ctype(
"" ) ) ) ;
Sehe ich ein.
Nur würde ich nie die Semantik vom ctype Facet ändern, weil es vom
z.B. std::num_get benutzt wird.
Natürlich erhebe ich nicht den Anspruch der Fehler freiheit. Aber
ich habe aus diesem Beispiel einiges gelernt.
|
Zum Lernen ist es interessant. Aber ich glaube nicht, dass ich es in
Produktionscode einführen würde. (Na ja, in jedem Fall habe ich sowieso
nicht die Gelegenheit. Mein Produktionscode muss u.a. mit g++ 2.95.2
kompiliert werden.)
--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|