Strange output from debugger on data from ifstream - c++

I open a file in read only mode, I read a line, and I cannot understand the meaning of the line contents as shown by the debugger:
#include <cctype>
#include <fstream>
#include <iostream>
#include <string>
int main()
{
std::string fidMapPath = "./file.txt";
std::ifstream ifsFidMap(fidMapPath);
if(ifsFidMap.good() == false) {
std::cerr << "Error" << std::endl;
exit(1);
}
std::string line;
while(ifsFidMap.eof() == false)
{
std::getline(ifsFidMap, line);
std::cout << "Line: " << line << std::endl;
}
}
This is the contents of the text file:
; Document title
123;456
123;123
456;456
...
When running, nothing is printed from the line variable; with the debugger, its contents is equal to "" (empty) before getline(), and \\000\\000\\000\\000... after, repeated up to a length of 2411 characters.
What is the meaning of this behavior?
These are my platform details:
Operating system: Windows 10, building remotely on Linux (Red Hat, kernel 2.6.32-431.5.1.el6.x86_64) through NetBeans 8.2.
Compiler: GCC 4.8.2 (C++11)
Debugger: GDB Red Hat Enterprise Linux 7.6.1-47.el6
P.S.: I tried, as suggested, to move the getline in the while argument:
while(std::getline(ifsFidMap, line))
but I still have the same issue.

With the version of GCC I used, 4.8.2, we must explicitly specify if what being compiled is C++11 code with the -std=c++11 compiler option. Otherwise it defaults to C++98.
This applies to GCC versions up to 5.x.

Related

std::stringsteam seems to break std::cout

#include <iostream>
#include <sstream>
int main() {
std::stringstream ss1;
std::cout << "hello";
}
For some reason, on VSCode on my Windows PC, the std::cout won't output anything when I have an std::stringstream line present but when I remove the line the output works. On my MacBook Pro this code runs normally in VSCode however.

Should I expect different behavior with fstream exception handling between CentOS6 and CentOS7?

I am reading data from file with an fstream object, while using exception handling. Because of how the logic is implemented, the code will execute a tellg() on the fstream after a fstream::failure exception is thrown when the end-of-file is hit. This execution flow is not necessarily intentional, but it hasn't caused any problems when running on Windows (MSVS 2010) or CentOS6. But, when running on CentOS7, I get a core dump. If I add a call to clear() the fstream prior to the tellg(), all is good.
There error that is thrown is:
terminate called after throwing an instance of 'std::ios_base::failure'
what(): basic_ios::clear
Can someone provide insight as to whether this change in behavior is expected, or not?
The applicable versions of gcc and libstdc++ are:
For CentOS6:
gcc version 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
/usr/lib64/libstdc++.so.6.0.13
For CentOS7:
gcc version 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC)
/usr/lib64/libstdc++.so.6.0.19
A code sample that exercises the issue follows:
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
fstream in;
in.exceptions(ifstream::failbit);
cout << "Before open" << endl;
in.open("in.txt", ios::in);
cout << "After open" << endl;
try
{
string s;
while ( 1 )
{
getline(in, s);
cout << s << endl;
}
}
catch(fstream::failure e)
{
cout << "EOF Exception." << endl;
}
catch(...)
{
cout << "Unhandled Exception." << endl;
}
// --- uncomment this to make it work --- in.clear();
in.tellg();
return 0;
}
Thanks for the help!
As shown in PR 26211 GCC 4.6.0 implements the resolution of DR 419, so the new behaviour is intentional.
There was a defect in the standard, which was fixed, and so GCC's library was changed to match the new specification in the standard.

string conversion with boost locale: different behaviour on windows and linux

This is my sample code:
#pragma execution_character_set("utf-8")
#include <boost/locale.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <iostream>
int main()
{
std::locale loc = boost::locale::generator().generate("");
std::locale::global(loc);
#ifdef MSVC
std::cout << boost::locale::conv::from_utf("grüßen vs ", "ISO8859-15");
std::cout << boost::locale::conv::from_utf(boost::locale::to_upper("grüßen"), "ISO8859-15") << std::endl;
std::cout << boost::locale::conv::from_utf(boost::locale::fold_case("grüßen"), "ISO8859-15") << std::endl;
std::cout << boost::locale::conv::from_utf(boost::locale::normalize("grüßen", boost::locale::norm_nfd), "ISO8859-15") << std::endl;
#else
std::cout << "grüßen vs ";
std::cout << boost::locale::to_upper("grüßen") << std::endl;
std::cout << boost::locale::fold_case("grüßen") << std::endl;
std::cout << boost::locale::normalize("grüßen", boost::locale::norm_nfd) << std::endl;
#endif
return 0;
}
Output on Windows 7 is:
grüßen vs GRÜßEN
grüßen
grußen
Output on Linux (openSuSE 12.3) is:
grüßen vs GRÜSSEN
grüssen
grüßen
On Linux the german letter 'ß' is converted to 'SS' as predicted, while this character remains unchanged on Windows.
Question: why is this so? How can I correct the conversion?
Some notes: Windows console codepage is set to 1252. In both cases locales are set to de_DE. I tried to replace the default locale setting in the listing above by "de_DE.UTF-8" - without any effect.
On Windows this code is compiled with Visual Studio 2013, on Linux with GCC 4.7, c++11 enabled.
Any suggestions are appreciated - thanks in advance for your support!
Windows doesn't do this conversion because "it would be too confusing" for developers if the string length changed all of a sudden. And boost presumably just delegates all the Unicode conversions to the underlying Windows APIs
Source
I guess the robust way to handle it would be to use a third-party Unicode library such as ICU.

Regex C Help on escape character

I am having trouble extracting the token values from my string : "JOIN #ROOM\r\n"
I am compiling my code on Mingw64 with the following arguments : g++ tregex.cpp -o tregex.exe -std=gnu++11
I get this error , but not my exception for some reason :
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
terminate called after throwing an instance of 'std::regex_error'
what(): regex_error
This is my code :
#include <regex>
#include <string>
#include <iostream>
using namespace std;
//Tregex.cpp
int main(void) {
regex rgx("[[:cntrl:]]");
string str = "JOIN #ROOM\r\n";
smatch match;
try{
if(regex_search(str, match, rgx))
for(auto token:match) cout << token <<"\n";
cout<< endl;
}
catch(regex_error & e){
if( e.code() == regex_constants::error_escape )
cerr << "invalid escape character \n";
else if( e.code() == regex_constants::error_stack )
cerr << "regular expression is not big enough\n";
else
cerr << "exception caught: "<< e.what()<<"\n";
}
cin.get();
return 0;
}
FWIW, there's nothing wrong with your C++ code, and it works perfectly using Clang and libc++ on my MacBook.
As indicated by the comments above, <regex> is one of the features that works in the LLVM project's libc++ but has never worked properly in the GNU project's libstdc++. You might try switching to libc++ if it's available for your platform.

How to compile and run C++0x with GCC/G++ in Eclipse CDT?

I am trying to figure out how to use the upcoming C++ release 0x. It should be available in GCC 4.3+ with using the gcc std=gnu++0x option.
My simple thread program using 0x compiles in Eclipse CDT with std=gnu++0x added in Project > properties > C/C++ Build > Settings > Miscellaneous > Other flags.
#include <iostream>
#include <thread>
using namespace std;
void hello()
{
cout << "Hello Concurrent World!" << endl;
}
int main()
{
cout << "starting" << endl;
thread t(hello);
t.join();
cout << "ending" << endl;
return 0;
}
The program only prints "starting" and returns 0. Does anyone know why it does not run the hello function threaded?
To use threads you also need to link against the threading library.
In case you haven't done that add -lpthread to your command line or in your case to other flags field.
The command line execute (visible in your console window in eclipse) should look like this:
gcc -std=gnu++0x -lpthread <source_file_name>.cc