I'm writing a C++ program that parses XML into JSON for a class and it works great when I compile in Visual Studio but behaves strangely when compiled with g++ in Linux.
With a bit of testing, I believe I have tracked the issue down into a difference in the way new lines are handled between the different compilers, here's some of the code I'm using to debug:
while (!fileToRead.eof()) { //Until we have reached the end of the file: ...
cout << endl << "newloop: ";
char c;
fileToRead.get(c);
cout << "read " << c << " ";
if (c != '\n' && c != '\t')
cout << "is a text character.";
}
When I run an executable created in Visual Studio, it outputs the following for new line characters it reads:
newloop: read
newloop: read
newloop: read
newloop: read
When I run it on Linux when compiled with g++, it outputs the following for new line characters it reads:
is a text character.
newloop: read
is a text character.
newloop: read
is a text character.
newloop: read
newloop: read
As you can see, when compiled with g++ there are 2 problems:
The third cout ("is a text character.") runs before the first and seconds couts ('"endl << << "newloop: "' and '"read " << c << "')
The if statement ("if (c != '\n' && c != '\t')") runs even when c is a new line character.
Can anyone explain what's going on here?
You are not parsing the same XML file. Even if it looks the same in a text editor.
My guess is, the one on windows contains CRLF newlines (\r\n or 0x0D 0x0A), the other only contains LF (\n or 0x0A) newlines.
Make sure you have the exact same file on either system, and you'll get the same results.
Related
I'm trying to write a .dat file using Windows subsystem for Linux, but the fstream library seems to bypass every endline command.
Here is my code:
int main()
{
string fname = "DataSheet.dat";
ofstream fdata (fname.c_str(), ios::out);
fdata << "First line" << endl;
fdata << "Second line" << endl;
fdata.close();
return = 0;
}
I tried substituting << endl with << "\n" and modifying the ofstream command like showed there, but nothing worked; the output was always First lineSecond line instead of First line and Second line on subsequent lines.
Besides, the code works perfectly well when I print the output to video using cout command or when I compile and run it on cygwin.
Is it a problem of Windows subsystem for Linux or am I missing something important?
By a comment.
Try substituting << endl with \r\n
This is due to the differences in the line endings of linux and windows.
In windows you need to add a carriage return and then the new line character.
While in linux there is not need for the carriage return.
The problem comes from the fact that you are compiling for linux so std::endl places the linux version line ending but you are trying to view the output in windows.
I want to print ≠ in the terminal. I tried
cout << '\u2248' << endl;
cout << '\U00002248' << endl;
cout << '≠' << endl;
which gives
14846344
14846344
14846368
I tried replacing the single quotes with double
Ôëê
Ôëê
Ôëá
How can it be done? I'm curious what the explanation for the output I'm getting is? I'm running Netbeans 9 but have tested directly from command line with g++ too. I think this should be possible because echo ≠ produces the correct output in the Windows command prompt.
So, in C++, like in plain C, by default we can work just with ASCII characters.
Char variables contains just 8 bits(1 byte) to store values so maximum - 2^8=256 different symbols can be coded by one char variable.
Single quotes (like 'a') are storing char variables so inside of them can be placed just ASCII-character. Your character is not a part of ASCII table and we need to change the encoding.
For just print(not store/process) your character, you should use another encoding such as UTF-8. You can do it programmatically:
std::setlocale(LC_ALL, /*some system-specific locale name, probably */ "en_US.UTF-8");
std::cout << "\u2260" << std::endl;
Or via command line options to g++ (such as -finput-charset=UTF-16).
As you can see, I'm using double quotes to print non-ASCII symbols to console.
Firstly, i'm a beginner in C++, be mercyful. I can't find an answer.
Hi, i'm trying to write a interpreter. And i select '\n' as line terminator, when i try this:
#define __TEST__ 1
while(Source >> Word){ //Source is file descriptor. I can't use EOF method because of if i do that, i will need to write two statments. Critical...
if(Word == '\n'){ // Word is a string object.
//Clean the vector
# if __TEST__
cout << "Succesful!" << "\n";
# endif
}
}
When i try to compile this code, it's gives an error because of " ' " token. When i change it with ' " ' token, compiler gives no error but when runtime, program can't detect end of line. What is the fastest way of solve this problem?
>> discards white space, so Word won't ever contain a line break.
If you want to read until the end of the line, you should use the getline function rather than >>.
This question already has answers here:
Why does reading a record struct fields from std::istream fail, and how can I fix it?
(9 answers)
Closed 8 years ago.
I'm trying to parse a .csv file, and I need to be able to test for a carriage return. Here is a test .csv file called sample.csv:
2
3
As you'll notice, there are two rows and one column in this file. I now write the following C++ code:
ifstream myfile (sample.csv); //Import file
char nextchar;
myfile.get(nextchar);
cout<<nextchar<<'\n';
myfile.get(nextchar);
cout<< nextchar<<" If 0, then that was not a carriage return. If 1, it was. :"<<(nextchar=='\n')<<'\n';
myfile.get(nextchar);
cout<<nextchar<<'\n';
I expect the following output:
2
If 0, then that was not a carriage return. If 1, it was. :1
3
however, I get:
2
If 0, then that was not a carriage return. If 1, it was. :0
3
How is this possible? how do I test for a carriage return??
It may be a pair of characters CR + LF. In any case you could output the code of this character yourself. Why did not you do this?
Also you could apply standard function std::isspace decalred in header <cctype>
I suggest to use standard function std::getline to read a whole line instead of using get.
There are a lot of things that can go wrong in the assumptions: OS behaviour, the text editor used to write the sample file, an undesired extra space or tab at the end of line, and the ios_base::openmode used to open the file, as well as all possible combination between those...
First instert this line to see what you actually read: is it 0x0d or 0x0a ? or somthing else ?
cout << "Char read: 0x0"<< std::hex << (int)nextchar<<"\n";
cout << "If 0 ... // Existing line
You can also replace your sample with the following. It opens the file in binary mode and display in hex the chars really in the file :
ifstream myfile ("sample.csv", ifstream::binary); //Import file
while (myfile.good() ) {
char nextchar;
myfile.get(nextchar);
if (myfile.good())
cout << "0x0"<< std::hex << (int)nextchar
<< " " << (isprint(nextchar)? nextchar:'?') <<"\n";
}
If second and third line are 0x0d and 0x0a, you'll know for sure that your text editor has put the extra CR.
Then you can remove ifstream::binary in the code above. Normally you should have, as you pointed out only 0x0a in the second line. If it's not the case, then you should investigate if the default openmode was somehow altered.
By the way, I've compiled your original code under windows and prepared the sample file using notepad , ran the programm and got... what you did expect ! Then I've redone the test with the following modification and the finally got what you got.
Good luck !
I have some issue when I want to print out \n I'm using endl for that. And the problem is when I run the code on Windows7 it won't print out the newline. But it will print out newline in Ubuntu. Both OS is using the same compiler GNU g++.
So I wonder if there are some different way to print newline to file in Windows?
void translate(ofstream &out, const string &line, map<string, string> m)
{
stringstream ss(line);
string word;
while(ss >> word)
{
if(m[word].size() == 0)
out << "A";
else
out << m[word] << " ";
}
out << "\n";
}
Outputting either '\n' or using endl will result in the exact same content (the only difference is endl also flushes). When that \n character is written, if the file is in "text mode", the runtime library converts it to the platform's native mechanism to indicate lines. On unix, this is unnecessary because that mechanism is a \n byte. On Windows, that \n becomes \r\n (carriage return, line feed). I suspect you know all of this, but I'm reviewing it just in case.
In short, as long as your runtime library is setup for Windows, the code you have will work as you expect. I suspect you are using cygwin's g++, or some other g++ port, that is not setup for Windows-style lines, even in text mode. Some editors will not correctly interpret that untranslated \n.