I'm able to std::wcout a variable on Windows, but not on Linux.

I'm trying to write a c++ application I can run on both Windows and Linux using the Microsoft cpprest lib. It's supposed to send a GET request to my server,and receive a JSON response back. On Windows, I'm able to pick what value from the json object and print to the console, but on Linux (raspberry pi 3) this same code runs into a compiler error. I'm not sure what I'm doing wrong because it works great on Windows.

Here's the code and compiler error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void printJSON(web::json::value & value) {
	if (!value.is_null()) {
		try {
			const auto y = value.at(U("type"));
			utility::string_t x = y.as_string();
			// Works on Windows, but crashes on Linux (Raspberry Pi)
                        std::wcout << x.as_string() << std::endl; // this is line 54
		}
		catch (web::json::json_exception &ex) {
		 	std::wcout << ex.what() << std::endl;
		}
	}
}

// Error Message

main.cpp: In function ‘void printJSON(web::json::value&)’:
main.cpp:54:18: error: cannot bind ‘std::wostream {aka std::basic_ostream<wchar_t>}’ lvalue to ‘std::basic_ostream<wchar_t>&&’
    std::wcout << x << std::endl;
                  ^
In file included from /usr/include/c++/4.9/istream:39:0,
                 from /usr/include/c++/4.9/sstream:38,
                 from /usr/local/include/cpprest/json.h:20,
                 from /usr/local/include/cpprest/http_msg.h:22,
                 from /usr/local/include/cpprest/http_client.h:35,
                 from main.cpp:5:
/usr/include/c++/4.9/ostream:602:5: note: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = wchar_t; _Traits = std::char_traits<wchar_t>; _Tp = std::basic_string<char>]’
     operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)

Last edited on
The line you show in the code snippet "std::wcout << x.as_string() << std::endl; // this is line 54" is not the same as the line you show in the error message snippet ("std::wcout << x << std::endl;").

Going by the error message, it is saying that it cannot compile operator<< with std::wstream on the left and std::string on the right. Wide streams take wide strings, if you have std::string, send it to std::cout.
(looking at this cpprest, https://microsoft.github.io/cpprestsdk/namespaceutility.html and utility::string_t appears to be defined as std::string)

How exactly does it work on Windows? on my Visual Studio 2017RC, a mock-up doesn't compile: I get E0349 from intellisense and C2679 from the compiler, both explaining how there is no "<<" that takes std::wstream on the left and std::string on the right.



Hi Cubbi, I probably pasted the wrong code, this is what I current have...this code prints out the json value on Windows, on Linux it doesn't crash..but nothing is printed...and it only gets to line 30. I'm compiling the same code on Linux, but no luck.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

void printJSON(web::json::value & value) {

	if (!value.is_null()) {
		try {
			auto y = value.at(U("type"));
			std::string str = utility::conversions::to_utf8string(y.as_string().c_str());
			std::cout << str.c_str() << std::endl;
		}
		catch (web::json::json_exception &ex) {
			std::wcout << ex.what() << std::endl;
		}
	}
	else {
	}
}

int main() {

	bool mainloop = true;

	web::http::client::http_client client(U("http://192.168.1.108:665/"));
	pplx::task<web::http::http_response> resp = client.request(web::http::methods::GET, U("api/test"));

	resp.then([=](web::http::http_response response) {
		if (response.status_code() == web::http::status_codes::OK) {
			auto bodyStream = response.body();
			size_t contentLength = response.headers().content_length();
			std::wcout << U("Content Length: ") << contentLength << std::endl;
                        // Linux only gets to here
			return response.extract_json();
		}
		
	}).then([](web::json::value j) {
		printJSON(j);
	});

	while (mainloop) {}

	return 0;
}

Last edited on
Try using this code to see what data is in json::value:
1
2
3
4
5
6
7
8
9
10
11
12
13
14

void printJSON(web::json::value & value) {
    if (!value.is_null()) {
        for(auto iter = value.as_object().cbegin(); iter != value.as_object().cend(); ++iter)
        {
            const utility::string_t &str = iter->first;
            const json::value &v = iter->second;
//          std::string str = utility::conversions::to_utf8string(U(str).as_string().c_str());
//          std::cout << str.c_str() << std::endl;
//          On linux string_t is string
            std::cout << str << std::endl;
        }
    }
}

I
Last edited on
on Linux it doesn't crash..but nothing is printed

you may be hitting the problem that C I/O (which underlies C++ I/O on Linux) can't handle both narrow and wide output on the same stream. The symptom of that is exactly "nothing is printed".

You can quickly test if that is the problem by switching your narrow output to a different C stream via std::clog << str.c_str() << std::endl;

(and to avoid guessing, it would be best to have a complete minimal test program others could run rather than bits of code)
Last edited on
What JSON library are you using? You don't include your #includes in your snippets. Check the docs for your JSON library, and make sure you're following their conventions properly.

I think that the web::json::value is a Microsoft namespace. Are you using a portable JSON parser?

If memory serves I had good success with jsoncpp on Linux with g++ compiler:
https://github.com/open-source-parsers/jsoncpp

Also, where is U declared? I don't see it anywhere. From the looks of things, I assume that U is your JSON object.
Last edited on
Topic archived. No new replies allowed.