C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CR/LF/CRLF

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Martin Herrmann
Guest





PostPosted: Sat Mar 12, 2005 4:12 pm    Post subject: CR/LF/CRLF Reply with 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?

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





PostPosted: Sun Mar 13, 2005 11:46 am    Post subject: Re: CR/LF/CRLF Reply with quote



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





PostPosted: Mon Mar 14, 2005 3:57 pm    Post subject: Re: CR/LF/CRLF Reply with quote



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





PostPosted: Mon Mar 14, 2005 9:06 pm    Post subject: Re: CR/LF/CRLF Reply with quote

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





PostPosted: Mon Mar 14, 2005 9:11 pm    Post subject: Re: CR/LF/CRLF Reply with quote

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





PostPosted: Mon Mar 14, 2005 11:14 pm    Post subject: Re: CR/LF/CRLF Reply with quote

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





PostPosted: Tue Mar 15, 2005 7:10 am    Post subject: Re: CR/LF/CRLF Reply with quote

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





PostPosted: Tue Mar 15, 2005 9:06 am    Post subject: Re: CR/LF/CRLF Reply with quote

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





PostPosted: Tue Mar 15, 2005 1:20 pm    Post subject: Re: CR/LF/CRLF Reply with quote

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





PostPosted: Mon Mar 21, 2005 7:47 pm    Post subject: Re: CR/LF/CRLF Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.