PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > getline() and newlines
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
getline() and newlines

Réponse
 
LinkBack Outils de la discussion
Vieux 05/04/2008, 14h25   #1
barcaroller
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut getline() and newlines


I have a text file with mixed carriage returns ('\n' and '\r\n').

On Linux, both the std::string getline() global function and the
std::iostream getline() member function are keeping some of the newlines in
the result (I suspect they look only for the '\n').

* Is there a quick way I can tell either function to gobble up both
Windows-style and Unix-style newlines?

* If not, what would be an efficient way of getting rid of them? Currently
I use string::find_last_of("\n\r") + string::erase() but this is not very
efficient.



  Réponse avec citation
Vieux 05/04/2008, 14h45   #2
Obnoxious User
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: getline() and newlines

On Sat, 05 Apr 2008 09:25:11 -0400, barcaroller wrote:

> I have a text file with mixed carriage returns ('\n' and '\r\n').
>
> On Linux, both the std::string getline() global function and the
> std::iostream getline() member function are keeping some of the newlines
> in the result (I suspect they look only for the '\n').
>
> * Is there a quick way I can tell either function to gobble up both
> Windows-style and Unix-style newlines?
>
> * If not, what would be an efficient way of getting rid of them?
> Currently
> I use string::find_last_of("\n\r") + string::erase() but this is not
> very efficient.


A simple and quick solution, adjust it to your own needs:

#include <iostream>
#include <sstream>

std::istream & getline(std::istream & in, std::string & out) {
char c;
while(in.get(c).good()) {
if(c == '\n') {
c = in.peek();
if(in.good()) {
if(c == '\r') {
in.ignore();
}
}
break;
}
out.append(1,c);
}
return in;
}

int main() {
std::istringstream strm("alpha\nbeta\n\r...\n\romega\n\n");
for(int i = 0; strm.good(); ++i) {
std::string line;
getline(strm,line);
std::cout<<i<<"\t"<<line<<std::endl;
}
return 0;
}

--
OU
  Réponse avec citation
Vieux 05/04/2008, 14h52   #3
Obnoxious User
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: getline() and newlines

On Sat, 05 Apr 2008 13:45:39 +0000, Obnoxious User wrote:

> On Sat, 05 Apr 2008 09:25:11 -0400, barcaroller wrote:
>
>> I have a text file with mixed carriage returns ('\n' and '\r\n').
>>
>> On Linux, both the std::string getline() global function and the
>> std::iostream getline() member function are keeping some of the
>> newlines in the result (I suspect they look only for the '\n').
>>
>> * Is there a quick way I can tell either function to gobble up both
>> Windows-style and Unix-style newlines?
>>
>> * If not, what would be an efficient way of getting rid of them?
>> Currently
>> I use string::find_last_of("\n\r") + string::erase() but this is not
>> very efficient.

>
> A simple and quick solution, adjust it to your own needs:
>
> #include <iostream>
> #include <sstream>
>
> std::istream & getline(std::istream & in, std::string & out) {
> char c;
> while(in.get(c).good()) {
> if(c == '\n') {
> c = in.peek();
> if(in.good()) {
> if(c == '\r') {
> in.ignore();
> }
> }
> break;
> }
> out.append(1,c);
> }
> return in;
> }
>
> int main() {
> std::istringstream strm("alpha\nbeta\n\r...\n\romega\n\n");
> for(int i = 0; strm.good(); ++i) {
> std::string line;
> getline(strm,line);
> std::cout<<i<<"\t"<<line<<std::endl;
> }
> return 0;
> }


Realized after I posted it that I reversed the sequence, so the code is
flawed for your needs. Although easily fixed. Ignore it.

--
OU
  Réponse avec citation
Vieux 05/04/2008, 15h07   #4
Erik Wikström
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: getline() and newlines

On 2008-04-05 15:25, barcaroller wrote:
> I have a text file with mixed carriage returns ('\n' and '\r\n').
>
> On Linux, both the std::string getline() global function and the
> std::iostream getline() member function are keeping some of the newlines in
> the result (I suspect they look only for the '\n').
>
> * Is there a quick way I can tell either function to gobble up both
> Windows-style and Unix-style newlines?


While you can specify the delimiting character you can only specify one
character.

> * If not, what would be an efficient way of getting rid of them? Currently
> I use string::find_last_of("\n\r") + string::erase() but this is not very
> efficient.


Since the Windows sequence is \r\n and getline() uses \n as delimiter
any line with a Windows linebreak will end with \r. Use this knowledge
to reduce the work required:

std::string str;
std::getline(file, str);

if (str[str.size() - 1] == '\r')
str.resize(str.size() - 1);

--
Erik Wikström
  Réponse avec citation
Vieux 05/04/2008, 20h02   #5
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: getline() and newlines

On 5 avr, 15:25, "barcaroller" <barcarol...@music.net> wrote:
> I have a text file with mixed carriage returns ('\n' and '\r\n').


> On Linux, both the std::string getline() global function and
> the std::iostream getline() member function are keeping some
> of the newlines in the result (I suspect they look only for
> the '\n').


Technically, it's implementation defined. Typically, however,
yes: Unix implementations treat a single 0x0A in the stream as a
newline; Windows implementations treat either a single 0x0A or
the sequence 0x0D, 0x0A as a newline.

Most of the time, this should not be a problem. In all of the
usual encodings (at least outside of the mainframe world), the
0x0D will result in an '\r' under Unix (and probably also under
Windows, if it isn't immediately followed by a 0x0A). In the
"C" locale, and probably in all other locales, '\r' is
whitespace. So it ends up ignored with the rest of the trailing
whitespace. (The one exception is C and C++ source code; for
some reason, the standard doesn't consider '\r' as whitespace in
source code.)

> * Is there a quick way I can tell either function to gobble
> up both Windows-style and Unix-style newlines?


Is there ever a need to?

> * If not, what would be an efficient way of getting rid of
> them? Currently I use string::find_last_of("\n\r") +
> string::erase() but this is not very efficient.


I'd use an external program (e.g. tr). In practice, if a file
is on a shared file system, and thus being read by both Windows
and Unix, it's generally best (pragmatically, at least) to stick
with the Unix conventions.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
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
  Réponse avec citation
Vieux 07/04/2008, 12h15   #6
Antoine Mathys
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: getline() and newlines

> std::string str;
> std::getline(file, str);
>
> if (str[str.size() - 1] == '\r')
> str.resize(str.size() - 1);


And with a empty line with unix end of line -> SEGFAULT

The code fragment should be:
if ((str.size() > 0) && (str[str.size() - 1] == '\r')
str.resize(str.size() - 1);
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 07h56.


Édité par : vBulletin® version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,11647 seconds with 14 queries