I wrote this simple program. I know that the printf() function in C returns the total number of characters successfully printed so the following C program works fine because any non-zero value is evaluated as true in C.
#include <stdio.h>
int main(void)
{
if (printf("C"))
return 0;
}
But why does the following C++ program compiles & runs fine? If cout is an object not a function, then why is the program giving the expected output?
#include <iostream>
using namespace std;
int main() {
if (cout << "C++")
// your code goes here
return 0;
}
std::cout << "C++";
is a function call to std::operator<<(std::cout, const char*) which returns a reference to std::cout which is convertible to bool. It will evaluate to true if no error on std::cout occurred.
The << operator returns cout. This is why you can chain the << operator like this:
std::cout << "Hello" << " " << "C++" << " " << "World!" << std::endl;
The returned cout will implicitly conver to the value true in the if.
I'm not exactly sure what you are trying to do but assuming you want your program to exit successfully if and only if the printing succeeded, you should write this in C:
#include <stdlib.h>
#include <stdio.h>
int
main()
{
if(printf("C") < 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
The reason is that printf will return a negative number to report errors and –1 is considered “true” as well.
The corresponding C++ program should look like this:
#include <cstdlib>
#include <iostream>
int
main()
{
if (!(std::cout << "C++"))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
The reason this works is that calling operator << on std::cout returns a reference to the stream itself, which also is why things like
std::cout << "You've got " << 99 << " points" << std::endl;
work. Each invocation returns a reference to std::cout upon which the next invocation is performed.
Now, std::basic_ios which std::cout is derived from, defines a conversion operator. Since C++11, this is declared as
explicit operator bool() const;
This means that if the stream is evaluated in a boolean context such as as the condition in an if statement, it is converted to a bool. The table at the bottom of the linked page shows under what conditions the returned bool will be true or false. In summary: it will return true unless an error occurred on the stream.
Before C++11 (when we didn't have explicit operators), a void * pointer was returned that was non-NULL if and only if no errors on the stream occurred. And again, a void * pointer can be evaluated in a boolean context.
Be aware that in both programs shown above, the tests could indicate success but the output may still fail. The reason for this is that output is usually buffered inside the program and only if enough output is gathered will the operating system be asked to actually do the output. You can request a flush at any time to make this happen now. In C, you would call fflush on the respective FILE * pointer.
#include <stdlib.h>
#include <stdio.h>
int
main()
{
if(printf("C") < 0 || fflush(stdout) < 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
In C++, you can use the std::flush constant.
#include <cstdlib>
#include <iostream>
int
main()
{
if (!(std::cout << "C++" << std::flush))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
If you also want a newline, you can use std::endl. Writing
std::cout << "hello, world\n" << std::flush;
has about the same effect as writing
std::cout << "hello, world" << std::endl;
Note however that output buffering is used for performance reasons so if you routinely flush your buffers after each and every output statement, you might well degrade the performance of your program.
Finally, in C++ you can also ask a stream to throw an exception if an error occurs. Since I/O errors should not happen during normal operation and repetitively checking for them can clutter your code, this might come in handy.
#include <cstdlib>
#include <iostream>
int
main()
{
std::cout.exceptions(std::ifstream::failbit);
try
{
std::cout << "C++" << std::flush;
return EXIT_SUCCESS;
}
catch (const std::ios_base::failure &e)
{
return EXIT_FAILURE;
}
}
If you want to test whether your program reports the correct exit status for failed I/O, you can try piping standard output to /dev/full on POSIX systems. /dev/full is a special file that pretends that nothing can be written to it because the file system's capacity is exceeded.
Because this is the same as writing
cout << "C++";
if(cout){
//do whatever
}
It just writes "C++" to cout and checks if your stream is still open.
Related
#include <cstddef>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
//read the lines from the piped file using cin
string response;
int i = 0;
while (getline(cin, response)) {
//if the response is empty, stop
if (response.empty()) {
break;
}
//Write each odd line (1,3, etc..) to stderr (cerr)
//Write each even line (2,4. etc..) to stdout (cout)
if (i % 2 != 1) { //send odd to stderr
cerr << "err: " << response << endl;
}
else { //send even to stdout
cout << "out: " << response << endl;
}
i++;
}
return 0;
}
I want to redirect stderr to /dev/null, how would I go about doing so? I'm new to C++ and trying to learn by practicing, however, I'm not easily able to find an answer that fits my existing program.
Besides the excellent commentary above, it is pretty easy to make a “null” streambuf sink in C++.
#include <iostream>
struct null_streambuf: public std::streambuf
{
using int_type = std::streambuf::int_type;
using traits = std::streambuf::traits_type;
virtual int_type overflow( int_type value ) override
{
return value;
}
};
To use it, just set the rdbuf:
int main()
{
std::cerr.rdbuf( new null_streambuf );
std::cerr << "Does not print!\n";
}
If you wish to be able to turn it off and on, you will have to remember the original and restore it, not forgetting to delete the new null_streambuf.
int main()
{
std::cerr << "Prints!\n";
auto original_cerr_streambuf = std::cerr.rdbuf( new null_streambuf );
std::cerr << "Does not print.\n";
delete std::cerr.rdbuf( original_cerr_streambuf );
std::cerr << "Prints again!\n";
}
This does have the objective effect of being compiled to code, which I suspect is the advantage you are looking for: the ability to dynamically enable and disable diagnostic output.
This is, however, the usual function of a debug build, where you use the DEBUG macro to decide whether or not to compile something (such as error output operations) into the final executable.
Keep in mind that this does not disable output on standard error via other means, but only through cerr.
#include <bits/stdc++.h>
using namespace std;
void scan_a_line_indefinitely()
{
// scan line indefinitely
string input_line;
while(getline(cin,input_line))
{
cout << input_line ; **// doesn't print if i use this line**
//cout << input_line << endl; **// if i use this line, it works fine**
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
scan_a_line_indefinitely();
return 0;
}
someone please help me understand the problem with this code.
i think the problem is with cout.tie() and cout.tie(), when i remove these, program works fine.
std::cout will flush under these conditions:
An input-stream which is tied to std::cout tries to read input.
You removed the ties.
iostreams are synchronized with stdio, thus effectively unbuffered.
You disabled the synchronization.
The buffer is full.
That takes a bit longer.
The program ends normally.
That comes too late for you.
There is a manual flush (stream.flush() which is called when streaming std::flush; stream << std::endl is equivalent to stream << stream.widen('\n') << std::flush).
You have none of those.
So, fix any of them and you will see your output earlier.
If only iostreams are used you can add a manual flush to the output :
std::cout.flush();
Or
std::cout << /* the output */<< std::flush;
Also:
std::cout << std::endl is equivalent to std::cout << '\n' << std::flush
#include <bits/stdc++.h>
using namespace std;
void scan_a_line_indefinitely()
{
// scan line indefinitely
string input_line;
while(getline(cin,input_line))
{
cout << input_line ; **// doesn't print if i use this line**
//cout << input_line << endl; **// if i use this line, it works fine**
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
scan_a_line_indefinitely();
return 0;
}
someone please help me understand the problem with this code.
i think the problem is with cout.tie() and cout.tie(), when i remove these, program works fine.
std::cout will flush under these conditions:
An input-stream which is tied to std::cout tries to read input.
You removed the ties.
iostreams are synchronized with stdio, thus effectively unbuffered.
You disabled the synchronization.
The buffer is full.
That takes a bit longer.
The program ends normally.
That comes too late for you.
There is a manual flush (stream.flush() which is called when streaming std::flush; stream << std::endl is equivalent to stream << stream.widen('\n') << std::flush).
You have none of those.
So, fix any of them and you will see your output earlier.
If only iostreams are used you can add a manual flush to the output :
std::cout.flush();
Or
std::cout << /* the output */<< std::flush;
Also:
std::cout << std::endl is equivalent to std::cout << '\n' << std::flush
Edit: Strerror appears to work. E.g., if errno = ERANGE, it outputs "Result too large".
The problem remains that errno is not changed from 0.
In Xcode, I've been trying out cerrno and strerror with the short code below. Xcode returns
sqrt(-1) = nan
Undefined error: 0
instead of
sqrt(-1) = -nan
Numerical argument out of domain,
as does, for example, cpp.sh.
Why is this happening?
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cerrno>
#include <cstring>
using namespace std;
int main() {
errno = 0;
cout << "sqrt(-1) = " << sqrt(-1) << endl;
cout << strerror(errno) << endl << endl;
return(0);
}
Whenever you want to check errno after an operation, you should always check it, and possibly store it, immediately after the operation that sets it. If you perform other function calls in between that check, even something as simple as printing to the terminal, you may be clobbering errno.
One possible reason why errno is becoming 0 is due to the fact that it is wrapped in the stream expressions, and there's no guarantee that iostream does not indirectly set (or unset) errno through its implementation.
If ever you want to check or print the errno reason, you will always want to store the result before you print it. For example:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cerrno>
#include <cstring>
int main() {
errno = 0;
// store errno immediately after the computation
const auto result = std::sqrt(-1);
const auto err = errno;
// then print
std::cout << "sqrt(-1) = " << result << std::endl;
std::cout << std::strerror(err) << std::endl << std::endl;
return 0;
}
Edit: From the discussions in the OP's comments, this appears to not be the reason for errno not being set -- but rather due to math_errhandling being set to 2. I am keeping this answer here for archival reasons, since the code in the original post could just as easily be seeing this result for the reasons described here.
I'm trying to use the ofstream class to write some stuff to a file, but all that happens is that the file gets created, and then nothing. I have some simply code here:
#include <iostream>
#include <fstream>
#include <cstring>
#include <cerrno>
#include <time.h>
using namespace std;
int main(int argc, char* argv[])
{
ofstream file;
file.open("test.txt");
if (!file) {
cout << strerror(errno) << endl;
} else {
cout << "All is well!" << endl;
}
for (int i = 0; i < 10; i++) {
file << i << "\t" << time(NULL) << endl;
}
file.flush();
file.close();
return 0;
}
When I create a console application, everything works fine, so I'm afraid this code is not completely representative. However, I am using code like this in a much larger project that - to be honest - I don't fully understand (Neurostim). I'm supposed to write some class that is compiled to a dll which can be loaded by Neurostim.
When the code is run, "test.txt" is created and then "No error!" is printed, as this is apparently the output from strerror. Obviously this is wrong however. The application runs perfectly otherwise, and is not phased by the fact that I'm trying to write to a corrupted stream. It just doesn't do it. It seems to me like there is no problem with permissions, because the file is in fact created.
Does anyone have any ideas what kind of things might cause this odd behavior? (I'm on WinXP Pro SP3 and use Visual C++ 2008 Express Edition)
Thanks!
Just a thought :- in your real code are you re-using your stream object?
If so, you need to ensure that you call clear() on the stream before re-using the object otherwise, if there was a previous error state, it won't work. As I recall, not calling clear() on such a stream would result in an empty file that couldn't be written to, as you describe in your question.
ofstream file;
file.open("test.txt");
Just a nit: you can combine that into a single line. ofstream file("test.txt");
if (file) {
cout << strerror(errno) << endl;
} else {
cout << "All is well!" << endl;
}
Your test is backwards. If file is true, it's open and ready for writing.
Also, I wouldn't count on strerror() working correctly on Windows. Most Windows APIs don't use errno to signal errors. If your failure is happening outside the C/C++ run-time library, this may not tell you anything interesting.
UPDATE Thinking more about this, failing to open a file via fstreams is not guaranteed to set errno. It's possible that errno ends up set on some platforms (espeically if those platforms implement fstream operations with FILE* or file descriptors, or some other library that sets errno) but that is not guaranteed. The official way to check for failure is via exceptions, std::io_state or helper methods on std::fstream (like fail or bad). Unfortunately you can't get as much information out of std::streams as you can from errno.
You've got the if statement wrong. operator void* returns NULL (a.k.a. false) if the file is not writable. It returns non-zero (a.k.a. true) if the file is writeable. So you want:
if (!file) {
cout << strerror(errno) << endl;
} else {
cout << "All is well!" << endl;
}
Or:
if (!file.good()) {
cout << strerror(errno) << endl;
} else {
cout << "All is well!" << endl;
}