 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Martin Herrmann Guest
|
Posted: Sat Mar 12, 2005 4:12 pm Post subject: CR/LF/CRLF |
|
|
Hallo,
ich möchte Textdateien einlesen, von denen nicht bekannt ist, welchen
Zeilentrenner sie verwenden. Die Datei im Binär-Modus zu öffenen ist
nicht so schwer, aber gibt es eine Funktion, die, ähnlich wie getline,
eine einzelne Zeile liegt, unabhängig davon, wie sie abgetrennt ist?
Falls nicht, muss ich die Zeilentrennung wohl selbst machen. Was wäre im
Sinne von C++ der beste Weg? Mit istreambuf_iterator über den von rdbuf ()
gelieferten streambuf iterieren und Anfang und Ende der Zeile
raussuchen und dann einen String mit zwei istreambuf_iterator
konstruieren (string::string (input_iterator start, input_iterator end))?
Gruß,
Martin
--
Mit ungefähr 100 Std/km deutlich abheben. Fahrt aufholen. Steigen bei
ca. 120 Std/km.
- Flughandbuch DR400/180 R
--
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 |
|
 |
Marcel Müller Guest
|
Posted: Sun Mar 13, 2005 11:46 am Post subject: Re: CR/LF/CRLF |
|
|
Hallo,
Martin Herrmann schrieb:
| Quote: | ich möchte Textdateien einlesen, von denen nicht bekannt ist, welchen
Zeilentrenner sie verwenden. Die Datei im Binär-Modus zu öffenen ist
nicht so schwer, aber gibt es eine Funktion, die, ähnlich wie getline,
eine einzelne Zeile liegt, unabhängig davon, wie sie abgetrennt ist?
|
Hmm, also bei mir funktionieren zumindest Unix und PC-Format
automatisch, wenn ich die Datei im Textmodus öffne. Mac habe ich nicht
probiert.
Aber das hängt letztlich von der Implementation der Runtime ab. Portabel
wird es vermutlich nur, wenn man es selber macht.
--
Marcel Müller
--
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 |
|
 |
m. willi Guest
|
Posted: Mon Mar 14, 2005 3:57 pm Post subject: Re: CR/LF/CRLF |
|
|
Martin Herrmann wrote:
| Quote: | ich möchte Textdateien einlesen, von denen nicht bekannt ist, welchen
Zeilentrenner sie verwenden. Die Datei im Binär-Modus zu öffenen ist
nicht so schwer, aber gibt es eine Funktion, die, ähnlich wie getline,
eine einzelne Zeile liegt, unabhängig davon, wie sie abgetrennt ist?
|
habe da code der für n (unix) und rn (windows) funktioniert - gemisch
möglich. eine mac version mit nur r sollte einfach zu erweitern sein.
ansonsten würde mich interessieren, was die profis davon halten, oder ob
jemand eine bessere version davon kennt und postet:
template <class charT, class traitsT>
std::basic_istream<charT, traitsT>& getline(std::basic_istream<charT,
traitsT>& is,
std::string& str)
{
std::ios_base::iostate _St = std::ios_base::goodbit;
bool _Chg = false;
str.erase();
std::istream::sentry _Ok(is, true);
if(_Ok)
{
std::istream::int_type _C = is.rdbuf()->sgetc();
for(; ; _C = is.rdbuf()->snextc())
{
if(std::istream::traits_type::eq_int_type(std::istream::traits_type::eof(),
_C))
{
_St |= std::ios_base::eofbit;
break;
}
else if(std::istream::traits_type::eq(_C, 'r'))
{
std::istream::int_type _CC = is.rdbuf()->snextc();
if(std::istream::traits_type::eq_int_type(std::istream::traits_type::eof(),
_CC))
{
_St |= std::ios_base::eofbit;
}
else if(std::istream::traits_type::eq(_CC, 'n'))
{
is.rdbuf()->sbumpc();
}
else
{
is.rdbuf()->sputbackc(_CC);
}
_Chg = true;
break;
}
else if(std::istream::traits_type::eq(_C, 'n'))
{
is.rdbuf()->sbumpc();
_Chg = true;
break;
}
else if(str.max_size() <= str.size())
{
_St |= std::ios_base::failbit;
break;
}
else
{
str += std::istream::traits_type::to_char_type(_C);
_Chg = true;
}
}
}
if (!_Chg)
_St |= std::ios_base::failbit;
is.setstate(_St);
return (is);
}
mfg markus
--
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 |
|
 |
Ernst Murnleitner Guest
|
Posted: Mon Mar 14, 2005 9:06 pm Post subject: Re: CR/LF/CRLF |
|
|
Marcel Müller wrote:
| Quote: | Hallo,
Martin Herrmann schrieb:
ich möchte Textdateien einlesen, von denen nicht bekannt ist, welchen
Zeilentrenner sie verwenden. Die Datei im Binär-Modus zu öffenen ist
nicht so schwer, aber gibt es eine Funktion, die, ähnlich wie getline,
eine einzelne Zeile liegt, unabhängig davon, wie sie abgetrennt ist?
Hmm, also bei mir funktionieren zumindest Unix und PC-Format
automatisch, wenn ich die Datei im Textmodus öffne. Mac habe ich nicht
probiert.
Aber das hängt letztlich von der Implementation der Runtime ab. Portabel
wird es vermutlich nur, wenn man es selber macht.
|
Bei mir hat es nicht funktioniert, wenn ich die Datei unter Windows
schreibe und unter Linux lese. Da erkannte getline den Umbruch nicht.
--
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 |
|
 |
Ernst Murnleitner Guest
|
Posted: Mon Mar 14, 2005 9:11 pm Post subject: Re: CR/LF/CRLF |
|
|
Martin Herrmann wrote:
| Quote: | Hallo,
ich möchte Textdateien einlesen, von denen nicht bekannt ist, welchen
Zeilentrenner sie verwenden. Die Datei im Binär-Modus zu öffenen ist
nicht so schwer, aber gibt es eine Funktion, die, ähnlich wie getline,
eine einzelne Zeile liegt, unabhängig davon, wie sie abgetrennt ist?
|
Du kannst ja eine neue Klasse von ifstream ableiten und getline
überladen. Ich verwende folgende Implementation (habe ich mal irgendwo
im Internet gefunden):
std::ifstream & my_ifstream::getline(char *s, std::streamsize n)
{
int c = 0;
std::streamsize nRead = 0;
while (!eof() && !fail() && nRead < n-1)
{
c = get();
if (c == -1)
{
setstate(failbit);
break;
}
if (c == 'r')
{
// look, if there is also a following 'n' and remove it, too
if (! fail())
{
c = get();
if (c != 'n')
putback(c);
}
break;
}
if (c == 'n')
break;
s[nRead] = c;nRead++;
}
s[nRead] = ' ';
return (*this);
}
--
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 |
|
 |
Marcel Müller Guest
|
Posted: Mon Mar 14, 2005 11:14 pm Post subject: Re: CR/LF/CRLF |
|
|
Ernst Murnleitner schrieb:
| Quote: | Marcel Müller wrote:
Hmm, also bei mir funktionieren zumindest Unix und PC-Format
automatisch, wenn ich die Datei im Textmodus öffne. Mac habe ich nicht
probiert.
Bei mir hat es nicht funktioniert, wenn ich die Datei unter Windows
schreibe und unter Linux lese. Da erkannte getline den Umbruch nicht.
|
Unter Unix hat textmode vs. binmode üblicherweise keinerlei
Konsequenzen. Die meisten DOS-, OS/2- und WinXX-Implementationen
akzeptieren im Textmodus üblicherweise auch das Unix-Format.
--
Marcel Müller
--
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 |
|
 |
Ernst Murnleitner Guest
|
Posted: Tue Mar 15, 2005 7:10 am Post subject: Re: CR/LF/CRLF |
|
|
Ernst Murnleitner wrote:
| Quote: | Du kannst ja eine neue Klasse von ifstream ableiten und getline
überladen. Ich verwende folgende Implementation (habe ich mal irgendwo
im Internet gefunden):
|
Ich habe hier das Wort "überladen" gebraucht. Ist aber nicht richtig, da
"überladen" ja bedeutet, dass man den gleichen Funktionsnamen aber
andere Parameter verwendet. Gibt es eigentlich einen Fachausdruck dafür,
wenn man in einer abgeleiteten Klasse eine Funktion neu definiert?
Ernst
--
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 |
|
 |
Tilman Kuepper Guest
|
Posted: Tue Mar 15, 2005 9:06 am Post subject: Re: CR/LF/CRLF |
|
|
Hi Martin,
| Quote: | [...] aber gibt es eine Funktion, die, ähnlich wie getline, eine
einzelne Zeile liegt, unabhängig davon, wie sie abgetrennt ist?
|
Eine moegliche Variante hat Markus ja bereits ins Rennen
geschickt. Hier kommt "mein" Versuch: Die Funktion getlinex()
basiert auf der getline()-Implementierung von STLport.
Viele Gruesse aus Aachen,
Tilman Kuepper
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
template<class TCh, class TTr, class TAl>
std::basic_istream<TCh, TTr>& xgetline(
std::basic_istream<TCh, TTr>& strm,
std::basic_string<TCh, TTr, TAl>& str)
{
typedef std::basic_istream<TCh, TTr> istream_type;
typedef std::basic_streambuf<TCh, TTr> streambuf_type;
size_t count = 0;
typename istream_type::sentry s(strm, true);
if(s)
{
const TCh cr(' 15'); // Carriage return
const TCh lf(' 12'); // Line feed
streambuf_type* pBuf = strm.rdbuf();
str.erase();
while(count < str.max_size())
{
typename TTr::int_type ch = pBuf->sbumpc();
if(TTr::eq_int_type(ch, TTr::eof()))
{
strm.setstate(istream_type::eofbit);
break;
}
else
{
++count;
TCh ch1 = TTr::to_char_type(ch);
if(TTr::eq(ch1, cr)) continue;
if(TTr::eq(ch1, lf)) break;
str.push_back(ch1);
}
}
}
if(!count || count >= str.max_size())
strm.setstate(istream_type::failbit);
return strm;
}
--
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: Tue Mar 15, 2005 1:20 pm Post subject: Re: CR/LF/CRLF |
|
|
Ernst Murnleitner wrote:
| Quote: | Ernst Murnleitner wrote:
Du kannst ja eine neue Klasse von ifstream ableiten und getline
überladen. Ich verwende folgende Implementation (habe ich mal irgendwo
im Internet gefunden):
Ich habe hier das Wort "überladen" gebraucht. Ist aber nicht richtig, da
"überladen" ja bedeutet, dass man den gleichen Funktionsnamen aber
andere Parameter verwendet. Gibt es eigentlich einen Fachausdruck dafür,
wenn man in einer abgeleiteten Klasse eine Funktion neu definiert?
|
Wenn sie virtuell ist, nennt man es "überschreiben". Wenn nicht, würde mir
nur "verdecken" einfallen, wobei das eher die Konsequenz als den Vorgang
selbst beschreibt.
--
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 |
|
 |
Martin Herrmann Guest
|
Posted: Mon Mar 21, 2005 7:47 pm Post subject: Re: CR/LF/CRLF |
|
|
Marcel Müller (2005-03-13):
| Quote: | Hmm, also bei mir funktionieren zumindest Unix und PC-Format
automatisch, wenn ich die Datei im Textmodus öffne. Mac habe ich nicht
probiert.
|
Bei mir (gcc, Linux) ist es so, dass Unix (LF) korrekt funktioniert und
PC (CR LF) ebefalls an LF getrennt wird. Das sieht dann je nach
Anwendung auch so aus, als ob es funktionierte, aber die Strings
enthalten halt alle ein CR am Ende.
Mac wird als eine einzige Zeile gelesen.
Gruß,
Martin
--
Mit ungefähr 100 Std/km deutlich abheben. Fahrt aufholen. Steigen bei
ca. 120 Std/km.
- Flughandbuch DR400/180 R
--
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
|
|