473,790 Members | 3,083 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

std::getline() behaves differently between platforms?

JML
Hi,

I have some code which parses a text file and creates objects based on
what is in the text file. The code works just fine on Windows, but when
I compile it using XCode on OS X the parsing goes all wrong. Is there
some known differences with file handling on OS X?

My code is quite long, but one of the defect parts looks like this
(sorry about the indentation - I'm new to posting code on a newsgroup):

//Begin adding NPCs, exits and collision boxes
while ( std::getline(fi lestream, str) ) {

//Look for regular NPC
if (str == "[NPC]") {
std::cout << "Found NPC. \n";
std::string name;
int x, y, w, h, co_x, co_y, co_w, co_h;
filestream >name >x >y >w >h >co_x >co_y >co_w >co_h;
m_NPCList.push_ back( CActor( this, name, x, y, w, h, co_x, co_y, co_w,
co_h ) );

//Look for a path
bool foundPath = false;
std::getline(fi lestream, str); //Finish previous line
std::getline(fi lestream, str);

if ( str == "[PATH:LOOP]" ) {
std::cout << "Looped path!\n";
foundPath = true; m_NPCList[m_NPCList.size( )-1].SetFollowMetho d( 0 );
}

if ( foundPath ) {
std::getline(fi lestream, str);
while ( str != "[END]" ) {
int x, y;
std::string::si ze_type loc = str.find( " ", 0 );
std::istringstr eam x_string(str.su bstr(0, loc));
std::istringstr eam y_string(str.su bstr(loc+1, str.length()-1));
x_string >x;
y_string >y;
m_NPCList[m_NPCList.size( )-1].AddPathNode( CPoint( x, y ) );
std::getline(fi lestream, str);
}
}
}
}

On Windows the code parses a file with this content just fine:
[NPC]
Batman 100 100 32 32 8 16 16 8
[PATH:LOOP]
100 100
200 100
200 200
100 200
[END]

But on OS X it goes wrong at around here:
std::getline(fi lestream, str); //Finish previous line
std::getline(fi lestream, str);
if ( str == "[PATH:LOOP]" ) {
Nov 20 '07 #1
6 6778
On Nov 20, 1:36 pm, JML <"marcus]FJERN["@larsen.dkwrot e:
Hi,

I have some code which parses a text file and creates objects based on
what is in the text file. The code works just fine on Windows, but when
I compile it using XCode on OS X the parsing goes all wrong. Is there
some known differences with file handling on OS X?

My code is quite long, but one of the defect parts looks like this
(sorry about the indentation - I'm new to posting code on a newsgroup):

//Begin adding NPCs, exits and collision boxes
while ( std::getline(fi lestream, str) ) {

//Look for regular NPC
if (str == "[NPC]") {
std::cout << "Found NPC. \n";
std::string name;
int x, y, w, h, co_x, co_y, co_w, co_h;
filestream >name >x >y >w >h >co_x >co_y >co_w >co_h;
m_NPCList.push_ back( CActor( this, name, x, y, w, h, co_x, co_y, co_w,
co_h ) );

//Look for a path
bool foundPath = false;
std::getline(fi lestream, str); //Finish previous line
std::getline(fi lestream, str);

if ( str == "[PATH:LOOP]" ) {
std::cout << "Looped path!\n";
foundPath = true; m_NPCList[m_NPCList.size( )-1].SetFollowMetho d( 0 );

}

if ( foundPath ) {
std::getline(fi lestream, str);
while ( str != "[END]" ) {
int x, y;
std::string::si ze_type loc = str.find( " ", 0 );
std::istringstr eam x_string(str.su bstr(0, loc));
std::istringstr eam y_string(str.su bstr(loc+1, str.length()-1));
x_string >x;
y_string >y;
m_NPCList[m_NPCList.size( )-1].AddPathNode( CPoint( x, y ) );
std::getline(fi lestream, str);

}
}
}
}

On Windows the code parses a file with this content just fine:
[NPC]
Batman 100 100 32 32 8 16 16 8
[PATH:LOOP]
100 100
200 100
200 200
100 200
[END]

But on OS X it goes wrong at around here:
std::getline(fi lestream, str); //Finish previous line
std::getline(fi lestream, str);
if ( str == "[PATH:LOOP]" ) {
I didn't read your entire message (busy at work right now), but,
generally these type of problems occur due to line terminator
differences between platforms. \r\n for windows and I'm not sure what
it is for MAC OS X (\n\r???, or simply \n). If you have a hex editor,
have a look at how the line terminators are set in the file.

You may also try opening the file in text mode and see what happens,
and then try opening it in binary mode and see what happens.

Now back to work...
Nov 20 '07 #2
<hs********@gma il.comwrote:
[...]
generally these type of problems occur due to line terminator
differences between platforms. \r\n for windows and I'm not
sure what it is for MAC OS X (\n\r???, or simply \n).
AFAIK it's \r\n for windows, \n for unix, and \r for Mac.

I can think of 3 options for making it work:

1. Demand that files be converted to the lf convention of the platform,
and open the files in text mode. (Drawback: files have to be converted
when moved between platforms)

2. Settle on one of the conventions and open the files in binary mode.
(Drawback: files must be authored in an editor that supports that
convention, or converted).

3. (what I'd prefer) Write a line-getter that copes with all 3 conventions.
(Drawback: slightly messy and bloated)
Nov 20 '07 #3
On Nov 20, 4:21 pm, "Ole Nielsby"
<ole.niel...@te kare-you-spamminglogisk. dkwrote:
<hsmit.h...@gma il.comwrote:
[...]
generally these type of problems occur due to line terminator
differences between platforms. \r\n for windows and I'm not
sure what it is for MAC OS X (\n\r???, or simply \n).
AFAIK it's \r\n for windows, \n for unix, and \r for Mac.
More correctly, it's CRLF for Windows, LF for Unix, and (was, at
least) CR for Mac. At the disk level. Within a program, the
line terminator is always '\n'. (Note that to add to the fun,
some Windows programs use CRLF as a line *separator*, not a line
*terminator*.)
I can think of 3 options for making it work:
1. Demand that files be converted to the lf convention of the platform,
and open the files in text mode. (Drawback: files have to be converted
when moved between platforms)
2. Settle on one of the conventions and open the files in binary mode.
(Drawback: files must be authored in an editor that supports that
convention, or converted).
3. (what I'd prefer) Write a line-getter that copes with all 3 conventions..
(Drawback: slightly messy and bloated)
In general, I would say that any serious program today that
handles text input generated by an editor should use 3 (except
that you probably don't need to worry about a special case for
Max). From experience, if I'm editing files, I'll use 2, simply
because Windows programs seem to be (on the average) more
tolerant about this than Unix programs. But if you're asking
your users to edit the files, then it's probably not an option:
while every serious developer I've ever met uses either emacs or
vim, neither are really very popular among everyday users (to
put it mildly).

Note that using 3 isn't anywhere near as messy and bloated as it
sounds. CR, as you mentionned, maps to '\r', and isspace('\r')
should return true. And since you'll normally want to trim
trailing whitespace from the lines anyway...

The real problem with 3 is that you can't use it reading from
cin.

(Note that 1 is fine *if* you're actually moving the files, as
individual files. FTP, also supports two modes. It becomes
more of a problem if you're transfering them in a compressed
archive, and downright impossible if you're reading them over a
remote mounted file system.)

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nov 20 '07 #4
JML
James Kanze wrote:
More correctly, it's CRLF for Windows, LF for Unix, and (was, at
least) CR for Mac. At the disk level. Within a program, the
line terminator is always '\n'. (Note that to add to the fun,
some Windows programs use CRLF as a line *separator*, not a line
*terminator*.)
I tried writing a new .txt file with an editor in OS X, and then the
file parses just fine on the OS X build. Yay for that, but it is not an
optimal solution of course. I think the solution must be to write a new
line-getter, that handles the different line terminators.
>3. (what I'd prefer) Write a line-getter that copes with all 3 conventions.
(Drawback: slightly messy and bloated)

In general, I would say that any serious program today that
handles text input generated by an editor should use 3 (except
that you probably don't need to worry about a special case for
Max).
Note that using 3 isn't anywhere near as messy and bloated as it
sounds. CR, as you mentionned, maps to '\r', and isspace('\r')
should return true. And since you'll normally want to trim
trailing whitespace from the lines anyway...
As I'm not the most experienced guy in writing text parsers in C++,
could you guys give me some more concrete advice on how to create a
better line-getter? :)
Nov 20 '07 #5
JML" <"marcus]FJERN[ wrote:
:: James Kanze wrote:
::: More correctly, it's CRLF for Windows, LF for Unix, and (was, at
::: least) CR for Mac. At the disk level. Within a program, the
::: line terminator is always '\n'. (Note that to add to the fun,
::: some Windows programs use CRLF as a line *separator*, not a line
::: *terminator*.)
::
:: I tried writing a new .txt file with an editor in OS X, and then
:: the file parses just fine on the OS X build. Yay for that, but it
:: is not an optimal solution of course. I think the solution must be
:: to write a new line-getter, that handles the different line
:: terminators.

Why?

Isn't the solution to have proper text files on each platform?

Note that, on some systems, the physical file doesn't store any
terminator at all. It uses a hidden length value instead. It might
also store the text in EBCDIC.

Even so, std::getline works with a '\n' line terminator.
Bo Persson
Nov 21 '07 #6
On Nov 21, 10:13 pm, "Bo Persson" <b...@gmb.dkwro te:
JML" <"marcus]FJERN[ wrote:
:: James Kanze wrote:
::: More correctly, it's CRLF for Windows, LF for Unix, and (was, at
::: least) CR for Mac. At the disk level. Within a program, the
::: line terminator is always '\n'. (Note that to add to the fun,
::: some Windows programs use CRLF as a line *separator*, not a line
::: *terminator*.)
:: I tried writing a new .txt file with an editor in OS X, and then
:: the file parses just fine on the OS X build. Yay for that, but it
:: is not an optimal solution of course. I think the solution must be
:: to write a new line-getter, that handles the different line
:: terminators.
Why?
Isn't the solution to have proper text files on each platform?
And what do you do with file systems that are mounted on two
different platforms. Most of the time I'm working under
Windows, the files are actually on a Unix machine somewhere,
being served up by Samba. And they're being read by Unix
machines at the same time.
Note that, on some systems, the physical file doesn't store any
terminator at all. It uses a hidden length value instead. It might
also store the text in EBCDIC.
True. You don't remote mount files systems with those, and the
file transfer program does (or should) take care of any mapping;
that's why FTP also has two modes.
Even so, std::getline works with a '\n' line terminator.
I'll admit that I don't see too much of a problem either. In
practice, there are two situations. If you've copied the files,
you should have remapped during the copy, so you'll have the
native separator. And remote mounting, in practice, means just
Unix and Windows: the Windows implementations I know of have no
problem with Unix line endings, and the Unix implementations
simply pass the CR up as a '\r', which is white space, and
should just get ignored. In practice, it's just not a problem.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nov 22 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
10956
by: Frank Schmitt | last post by:
Hi! I've just been bitten by the famous Windows newline issue, i.e. tried to read a textfile written by a windows application on an unix platform. When reading a line with std::getline(input,buf); GCC 3.2 leaves a trailing '\r' in buf. Is this standard conformant? My impression was that getline
5
7751
by: vknid | last post by:
Hello, I have a question. Its probably a very newbish question so please be nice hehe. =D I have been reading through C++ Programming Fundamentals, and have come a crossed an example program that shows how to use the 'getline' function. It said: "The getline function allows you to specify how many bytes you will get from the users input. Each character the user's types takes up one byte. So if, in the getline function, you specify...
10
5619
by: Skywise | last post by:
I keep getting the following error upon compiling: c:\c++ files\programs\stellardebug\unitcode.h(677) : error C2664: 'class istream &__thiscall istream::getline(char *,int,char)' : cannot convert parameter 1 from 'const char *' to 'char *' Conversion loses qualifiers I have a data file called Standard.udf The Data File (not the problem): The data in the file is in text format, and was created using a function in this program with...
4
5744
by: sam | last post by:
Hi, How can I use getline ignore the commandline arguments? Thanks Sam
7
2463
by: Vladimir Lushnikov | last post by:
Hi, I have just started learning C++ and have been trying to do simple string manipulation. However, when calling this function: int helloString() { string name; cout << "Please enter your name:\n";
18
8258
by: Amadeus W. M. | last post by:
I'm trying to read a whole file as a single string, using the getline() function, as in the example below. I can't tell what I'm doing wrong. Tried g++ 3.2, 3.4 and 4.0. Thanks! #include <iostream> #include <fstream> #include <cstdlib> #include <string>
2
1978
by: aGAric | last post by:
i use std::getling to read a line in unicoude file to buffer,like: WCHAR buf wifstream in; std::getling(buf,in,100); but i can't get the right result,it seems can only read by 1 byte;e.g first word of unicode file is "0xfffe" ,if use getline ,it may 0x00ff 0x00fe in my buffer do you have any idea,except use c lib like fgetws
2
6014
by: Bit Byter | last post by:
I have a method in a class implemented like this: int foo (const char* filename, bool flg) { FILE *fp; char *buffer, *tokstr, *tmp; size_t size, toksize; unsigned int i; if ((fp = fopen(filename, "r")) == NULL)
1
4049
by: Kevin Eller | last post by:
I haven't used std::getline for a long time, if someone can help me
0
9666
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9512
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
10147
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9987
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9023
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6770
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5424
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5552
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3709
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.