Why doesn't my function produce output - c++

I'm doing a C++ assingment for a class and I haven't used C++ in a decade so this might be something I'm missing that is simple; however ,I can't seem to figure it out.
I have a class I defined with a function that is producing no output; it looks like it's not even running and I don't have a clue why. Could someone point out my problem to me?
Issue: cout from the function getwords of the class readwords doesn't display any results.
Here is my class:
class readwords {
private:
char c;
//string aword;
public:
void getwords(std::istream& file) {
cout << "I got here" << std::flush;
/*while(file.good()) {
cout << "I got here\n";
c = file.get();
if(isspace(c)) cout << "\n"; //continue;
if(isalnum(c)) {
cout << c; //aword.insert(aword.end(),c);
}
}
*/
}
};
Which is being called from my main:
#include <fstream>
#include <stdlib.h>
#include "lab1.h"
using namespace std;
readwords wordsinfile;
words wordslist;
int main ( int argc, char *argv[] )
{
if ( argc != 2 ) {
// Looks like we have no arguments and need do something about it
// Lets tell the user
cout << "Usage: " << argv[0] <<" <filename>\n";
} else {
// Yeah we have arguements so lets make sure the file exists and it is readable
ifstream ourfile(argv[1]);
if (!ourfile.is_open()) {
// Then we have a problem opening the file
// Lets tell the user and exit
cout << "Error: " << argv[0] << " could not open the file. Exiting\n";
exit (1);
}
// Do we have a ASCII file?
if (isasciifile(ourfile)) {
cout << "Error: " << argv[0] << " only can handle ASCII or non empty files. Exiting\n";
exit(1);
}
// Let ensure we are at the start of the file
ourfile.seekg (0, ios::beg);
// Now lets close it up
ourfile.close();
}
// Ok looks like we have past our tests
// Time to go to work on the file
ifstream ourfile2(argv[1]);
wordsinfile.getwords(ourfile2);
}
Thank you for any help you can provide.

Try to use a debugger. Most IDEs (NetBeans, Code::Blocks, etc) provide an interactive interface with gdb.

I just compiled and ran your code, but nothing wrong with the code itself,
except that I needed to include to use the 'cout' method.
"I got here" has been successfully displayed in my ubuntu machine.
What is your execution environment? You should check it first.

The problem appears to be redefining my own class. When actually coding the function I needed to use:
in readwords::countwords(std::istream& file) {
....
}
Once doing this output produced fine.

Related

How do I redirect stderr to /dev/null in C++?

#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.

fstream test program crashes for some reason

I have been playing around with the fstream class in C++ to see if I am able to write some data to a text file(.txt). According to what I know, If the program tries to write to a file that does not exist then it would automatically create that file, am I wrong? This program is very simple and does not give me any compiler errors which means it builds fine. However for some reason it crashes when I run it.
Here is my code:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <fstream>
std::fstream* myFile;
int main()
{
int age = 15;
std::string myName = "Javier Martinez";
std::string friendsName = "David Lyn";
//Backslash is a special character, use double backslash or forward slash instead.
myFile->open("C:/Users/NIKE/Desktop/data.txt");
if (myFile->fail())
{
std::cerr << "File was unable to be opened.";
}
*myFile << age << "\n";
*myFile << myName << "\n";
*myFile << friendsName << "\n";
myFile->close();
std::cout << "File was successfully written to with the data";
return 0;
}
Any help is appreciated. Thank you in advance.
NOTE: I am using the GNU GCC compiler with Code::Blocks IDE
myFile is uninitialized. Check it.( Allocate memory) or simply use fstream.
Your problem stems from the line:
std::fstream* myFile;
You only declared a pointer to a stream object, which is initialized to nullptr by reason of it being in the global scope. The fact that you tried accessing a non-existent object (invalid) through it, you invoked what is known as Undefined Behavior.
You do not need to allocate stream objects on the heap, rather, do:
std::fstream myFile;
On a side Note: Check your program control flow:
if (!myFile)
{
std::cerr << "File was unable to be opened.";
}
else{
myFile << age << "\n";
myFile << myName << "\n";
myFile << friendsName << "\n";
}

Using a C++ .exe with C++ : C++ception [duplicate]

This question already has answers here:
launch an exe/process with stdin stdout and stderr?
(3 answers)
Closed 8 years ago.
I need some help on this subject.
I have a C++ .exe that I want to open with C++ and then write some arguments in the console.
Here is an example of what I want to do:
Lets assume an executable whatsyourage.exe with this code (in reallity, I don't have the corresponding code):
#include <iostream>
using namespace std;
int main()
{
int age = 0;
cout << "What's your age ?" << endl;
cin >> age;
cout << "You are " << age << " year !" << endl;
return 0;
}
and I want to do something like:
int main()
{std::string invit="21";
std::string chemin ="whatsyourage.exe";// in the same library
std::string const command = chemin+" "+ invit;
system(command.c_str());
}
I want to write the age (21).
Can someone please help me?
Here is the answer:
int main()
{std::string invit="21";
std::string chemin ="whatsyourage.exe";
FILE* pipe = _popen(chemin.c_str(), "w");
if (pipe == NULL) {
perror("popen");
exit(1);
}
fputs("30", pipe);// write the age into the pipeline
pclose(pipe); // close the pipe
}
The popen() function from POSIX does what you are looking for. It allows you to execute a program (like system) while getting a file handle on its input/output streams.
For Windows, if popen() is not available, you can use the CreatePipe() & co functions to do the same thing; check out this question for some pointers.
The second snippet you added is good, and the problem is with the first code. In order to handle the command line from a program, you have to define the main as int main(int numberOfArguments, char* arguments[]) (often people use the shorter version - main(int argc, char* argv[]), but you can name the arguments as you wish). Then, if you pass an argument to the function, it will be in argv[1], since argv[0] is always the path to the executable. So the first program should look like this:
int main(int numberOfArguments, char* arguments[])
{
if(numberOfArguments>=2)
cout << "You are " << arguments[1] << " year !" << endl;
else
cout << "Too few arguments passed!" << endl;
return 0;
}

how to restore std::cin to keyboard after using pipe?

Problematic code:
#include <array>
#include <iostream>
#include <cstring>
int main(int argc, char *argv[])
{
using namespace std;
cout << "Read from file:" << endl;
while (!cin.eof())
{
array<char, 16> l_array;
cin.read(l_array.data(), l_array.size());
cout.write(l_array.data(), cin.gcount());
}
cout << endl;
cout << "Read from keyboard:" << endl;
cin.rdbuf(cout.rdbuf());
while (!cin.eof())
{
array<char, 64> l_array;
memset(l_array.data(), 0, l_array.size());
cin.read(l_array.data(), l_array.size());
cout << "===== DATA =====" << endl;
cout << l_array.data() << endl;
cout << "================" << endl;
}
}
This is how i run my program:
./application < file.txt
I can read data from pipe without problems but when i want to read it again it is still asociated with pipe. I have no idea how to switch it back. I have found 'rdbuf' function which can change it, but I have no idea how to use it.
I only found examples when you stard with keyboard switch to file and back to keyboard.
Like here: http://www.cplusplus.com/reference/iostream/ios/rdbuf/
But i don't have streambuf remembered so I can't do it like they did. I want to write program which can read most of data from file, and ask only when something is missing or just to ask user in runtime about permision or something. All inside console under linux.
#EDIT
Thank you for help, I post solution
class RedirectCinToConsole
{
protected:
std::ifstream m_console;
std::streambuf *m_oldCin;
bool m_success;
public:
RedirectCinToConsole() :
m_oldCin(0),
m_success(false)
{
m_console.open("/dev/tty");
if (m_console.is_open())
{
m_success = true;
m_oldCin = std::cin.rdbuf(m_console.rdbuf());
}
}
virtual ~RedirectCinToConsole()
{
if (m_oldCin)
{
std::cin.rdbuf(m_oldCin);
}
m_console.close();
}
operator bool () const { return m_success; }
};
int main()
{
RedirectCinToConsole l_redirect;
if (l_redirect)
{
std::string l_helloWorld;
std::cin >> l_helloWorld;
std::cin.ignore();
std::cout << l_helloWorld;
}
return 0;
}
It occurs to me that, regardless of the proposed solutions, the easiest
solution (and probably the best) would be to do things the opposite:
don't redirect the input, but pass the filename to the program, and let
it open an std::ifstream to read it, keeping std::cin free for
interactive input.
Ben Voigt has suggested the standard Unix solution, but on thinking
about it, it seems the above is more natural; it is certainly easier and
more portable.
Perhaps you should use fstream to create your own stream and either ask for a file name or take the file name as a command-line parameter. This will leave cin available for other input operations.
Try opening /dev/tty. This will be your process's associated console, if there is any. If your process was started from a daemon, it could fail.

Why does ofstream sometimes create files but can't write to them?

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;
}