Clearing the cout buffer (c++) - c++

Hello I'm writing a short program to implement a shell and I'm running into an unusual problem. For some reason I can't clear to the std::cout buffer. The program wont print out messages. I understand a simple solution is to switch to std::cerr, but is there a way to get messages to print with cout?
Things I've tryed:
std::cout.flush()
Inserting std::endl after anything is written to standard out.
Inserting an std::flush into the output stream
std::cout.setf(std::ios::unitbuf); which was something I found that should unbuffer output.
Any help is much appreciated here is my code:
int main()
{
//Tryed this to unbuffer cout, no luck.
std::cout.setf(std::ios::unitbuf);
std::string input;
//Print out shell prompt and read in input from keyboard.
std::cout << "myshell> ";
std::getline(std::cin, input);
//**********************************************************************
//Step 1) Read in string and parse into tokens.
//**********************************************************************
char * buf = new char[input.length() + 1];
strcpy(buf, input.c_str());
int index = 0;
char * command[256];
command[index] = std::strtok(buf, " "); //Get first token.
std::cout << command[index] << std::endl;
while (command[index] != NULL)
{
++index;
command[index] = std::strtok(NULL," "); //Get remaining tokens.
std::cout << command[index] << std::endl;
}
std::cout.flush(); //No luck here either
//HERE IS WHERE MY PROBLEM IS.
std::cout << index << " items were added to the command array" << std::endl;
delete[] buf;
return 0;
}

The problem is that you're sending NULL to cout on the last iteration of the while loop, which leads to UB, and in your case is jamming cout. Check for NULL before you send anything to cout and you're fine:
if (command[index] != NULL) {
std::cout << command[index] << std::endl;
}

If you ever need to know what happened to your streams, remember that they can carry status information (the iostate, which I recommend you read about). The following code could have helped track your error:
try {
std::cout.exceptions(std::cout.failbit);
} catch(const std::ios_base::failure& e) {
std::cerr << "stream error: " << e.what() << std::endl;
std::cout.clear();
}
// continue working with cout, because std::cout.clear() removed
// failbit
Or, even simpler:
if(not std::cout) {
// address your error (if it is recoverable)
}
This is how your code would have looked like:
#include <cstring>
#include <string>
#include <iostream>
int main()
{
//Tryed this to unbuffer cout, no luck.
std::cout.setf(std::ios::unitbuf);
std::string input;
//Print out shell prompt and read in input from keyboard.
std::cout << "myshell> ";
std::getline(std::cin, input);
//**********************************************************************
//Step 1) Read in string and parse into tokens.
//**********************************************************************
char * buf = new char[input.length() + 1];
strcpy(buf, input.c_str());
int index = 0;
char * command[256];
command[index] = std::strtok(buf, " "); //Get first token.
std::cout << command[index] << std::endl;
while (command[index] != NULL)
{
++index;
command[index] = std::strtok(NULL," "); //Get remaining tokens.
std::cout << command[index] << std::endl;
}
// I added from here...
if(not std::cout) {
std::cerr << "cout is messed up... fixing it..." << std::endl;
std::cout.clear();
}
// ... to here.
std::cout.flush(); //No luck here either
//HERE IS WHERE MY PROBLEM IS.
std::cout << index << " items were added to the command array" << std::endl;
delete[] buf;
return 0;
}
Result:
$ ./a.out
myshell> 1 2 3
1
2
3
cout is messed up... fixing it...
3 items were added to the command array

Related

Segmentation fault: unable to fix the problem

I'm new to C++, and I'm trying to write a project that interacts through command line. Right now, whenever I run my main (which is the executable), I always receive a segmentation fault error when the main program finished.
Edit comment:
I'm told by tutor to use as little as C++ features such as vectors or strings ... I'm also very new to C++, so i'm trying to utilize as many basic C functions as I can.
I'm
My main function looks like this:
int main(int argc, char** argv) {
cout << "starting mvote..." << endl;
int run_flag = 1;
char* actionBuffer = (char*)malloc(100 * sizeof(char));
char* action = (char*)malloc(16 * sizeof(char));
char* readPtr;
char exit[4] = { 'e','x','i','t' };
//parse command line argumentand get the filename
char* filename = argv[2];
cout << filename;
FILE* fp;
char line[64];
//from here, I'm opening the file and read it by lines
fp = fopen(filename, "r");
if (fp == NULL) {
cout << "file not exists";
return -1;
}
while (fgets(line, 64, fp) != NULL) {
cout << line << "\n";
}
fclose(fp);
while (run_flag == 1) {
cout << "what do you want?\n " << endl;
cin.getline(actionBuffer, 1024);
if (strcmp(actionBuffer, exit) == 0) {
cout << "bye!";
run_flag = 0;
break;
}
//if not exit, Look for the space in the input
readPtr = strchr(actionBuffer, ' ');
int size = readPtr - actionBuffer;
//extract the operation
strncpy(action, actionBuffer, size);
for (int i = 0; i < size; i++) {
cout << "operation:" << action[i];
}
// depend on the operation specified before the first empty space
run_flag = 0;
}
free(actionBuffer);
free(action);
return 0;
}
Description:
I first try to open up a csv file which lies in the same folder as main, and I read the file line by line. Then, I just implement a simple command where you can type exit and quit the program.
I allocate two memory, actionBuffer and action, which are used to hold command
Problem: a segmentation fault [core dumped] always exists when I type exit and hit enter, and then the process finished.
Research: So I learned that segmentation fault is due to accessing a memory that does not belongs to me. But where in my program am I trying to access such a memory?
Any advice is appreciated! Thank you.
Just to give you an idea, this would be an example of C++ code
#include<iostream>
#include<fstream>
#include<string_view>
#include<string>
#include<sstream>
#include<exception>
int main(int argc, char** argv) {
std::cout << "starting mvote...\n";
//parse command line argumentand get the filename
std::string filename = argv[2]; // NO CHECKS!
std::cout << filename <<'\n';
//from here, I'm opening the file and read it by lines
{
std::ifstream ifs(filename);
if (!ifs) {
throw std::invalid_argument("file not exists");
}
std::string line;
while (std::getline(ifs, line)) {
std::cout << line << '\n';
}
}
bool run_flag = true;
while (run_flag) {
std::cout << "what do you want?\n";
std::string userInput;
std::getline(std::cin, userInput);
if (userInput == "exit") {
std::cout << "bye!\n";
return 0;
}
std::stringstream userInputSs(userInput);
std::string operation;
while(userInputSs >> operation){
std::cout << "operation: " << operation << '\n';
}
}
}

getline function doesn't seem to be working in c++

ifstream read;
read.open(name);
char g[3];
read.getline(g,3);
char v = read.get();
cout << v;
read.close();
the issue i'm having is that after the getline function, the get is set to garbage and the file doesn't read properly anymore. However im sure that the file im reading contains more characters than getline takes, so what is issue?
Did you check that the read worked?
When you use a read always check the read worked before using the value:
if (read.getline(g,3)) {
// Read worked correctly
std::cout << "Got: >" << std::string(g, read.gcount()) << "<\n";
}
else {
std::cerr << "Read Failed\n";
throw "Failed";
}
if ((v = read.get()) != EOF) {
std::cout << "Got: >" << v << "<\n";
}
else {
std::cerr << "Read Failed\n";
throw "Failed";
}
Read file by std::fstream:
std::string str;
std::fstream file = "test.txt";//write in text.txt: GhY67. Test.
while(getline(file, str))//while get line of test.txt file,
// saves
// line in str string.
{
std::cout << str << '\n';
//Outputs str string(all lines in test.txt document)
}
If your wish always input characters, write this code:
std::string str;
while(getline(std::cin, str))//while getline in console, user
//inputs characters and characters in onr line saves in str
//string.*
{
if(str == "What?")
{
std::cout << "Hello, world!";
//*If user inputs string "What?", console outputs
string "Hello, world!*/
}
}

failbit getting set with ifstream object, what can be the cause?

I have written a small C++ program to set a property in a text file. The implementation is as following:
#include <cstdio>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
const string PROPFILE = "./propfile";
const string TEMPFILE = PROPFILE + ".tmp";
int setProp(const string &key, const string &val) {
try {
ifstream original(PROPFILE, ios::in);
ofstream tempfile(TEMPFILE, ios::out | ios::trunc);
for (string line; getline(original, line); ) {
if (line.compare(0, key.size(), key) == 0 && line[key.size()] == '=') {
tempfile << key << '=' << val << endl;
} else {
tempfile << line << endl;
}
}
cout << "original.rdstate()" << original.rdstate() << endl;
original.close();
tempfile.close();
} catch (ifstream::failure e) {
cerr << e.what() << endl;
}
if (rename(TEMPFILE.c_str(), PROPFILE.c_str()) != 0) {
cout << "Could not move " + TEMPFILE << "to " << PROPFILE << endl;
return 1;
}
return 0;
}
int main(int argc, const char *argv[]) {
try {
return setProp(argv[1], argv[2]);
} catch (logic_error) {
cout << "Invalid args" << endl;
return 1;
}
}
However, when I try to compile and execute it from commandline via ./a.out TESTPROP TESTVALUE, the value IS set as expected in propfile but rdstate() returns 6 (which means failbit and eofbit are set), I can't understand why are they getting set, can somebody explain ?
Contents of propfile before running ./a.out TESTPROP TESTVALUE are:
TESTPROP=NOTHING
After running the progam:
TESTPROP=TESTVALUE
I'm just a student, please don't mind if it's a dumb question :)
This is expected behaviour, the failbit is set whenever there is a failure to read the expected value. Even if that failure is because of end of file.
For instance see here
If no characters were extracted for whatever reason (not even the
discarded delimiter), getline sets failbit and returns.

C++ (pre C++11) fstream initialized by sstream

I am trying to open other process stdin and write to it, using C++, no dup() and other C tricks. But unfortunately, fstream constructor taking string seems to be available only from C++11 ( source:http://www.cplusplus.com/reference/fstream/fstream/fstream/ )
#include <iostream>
#include <fstream>
#include <sstream>
//using namespace std;
int main()
{
pid_t pid = fork();
if (pid == 0)
{
// std::cout << "child:" << i << std::endl;
std::string line;
std::cin.sync();
std::cout << "child got message:" << std::endl;
while ( std::getline(std::cin, line) )
{
std::cout << line << std::endl;
}
std::cout << "child done receiving" << std::endl;
}
else{
//std::cout << "parent"<<std::endl;
std::ifstream file("stdin", std::ios::in);
if(file.is_open())
{
std::string tmp, str;
std::stringstream pidstr;
pidstr << "/proc/" << pid << "/fd/0";
while ( std::getline(file, tmp) )
str += tmp + "\n";
std::fstream other( (pidstr.str().c_str()), std::ios::out);
other << str ;
}
}
return 0;
}
I have four questions:
Is "pidstr.str().c_str()" most C++ way to do it? Looks ugly to me.
Is that proper C++ way or maybe there are better alternatives?
Since, as far as I know, getline() is blocking, can I ommit cin.sync(), expecting child to wait for input in while ?
Why do I need to press enter twice, (regardless if i have getchar in child commented out or not(!))
Thanks for understanding.
EDIT: This compiles, and produces desired output, using Code:Blocks, Linux 13.04
EDIT2: No, apparently this does NOT produce desired output. I've added some changes: parent waits for child to exit (not important here).
But also changed this (in child) :
while ( std::getline(std::cin, line) )
{
std::cout << line << std::endl;
}
std::cout << "child done" << std::endl;
to this :
std::getline(std::cin, line);
int lines; // this is single line sent as first from parent, containing int
std::istringstream toint(line);
toint >> lines;
std::cout << "how much lines should it read:" << lines << std::endl;
And it appears that child will wait for anything on stdin, then prints out that what was sent from parent. Really, sometimes I wonder how should i consider C++ as better than plain C :/

C++ getting a seg fault before even entering a function

I have a problem where I try to compress a file's data. Everything works up to the compression call, but it isn't the compression call itself, as the segfault is thrown before it. Showing my code will make it much clearer:
std::cout << "FILENAME: ";
std::cin >> filename;
if(!fileExists(filename))
{
std::cout << "ERR: FILE NOT FOUND." << std::endl;
continue;
}
std::cout << "Compressing file data...";
writeFile(filename, zlib_compress(readFile(filename)));
std::cout << " Done." << std::endl;
At the function zlib_compress...
std::string zlib_compress(const std::string& str)
{
std::cout << "DEBUG" << std::endl;
z_stream zs; // z_stream is zlib's control structure
memset(&zs, 0, sizeof(zs));
if (deflateInit(&zs, 9) != Z_OK)
std::cout << "deflateInit failed while compressing." << std::endl;
zs.next_in = (Bytef*)str.data();
zs.avail_in = str.size(); // set the z_stream's input
int ret;
char outbuffer[1073741824];
std::string outstring;
// retrieve the compressed bytes blockwise
do
{
zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
zs.avail_out = sizeof(outbuffer);
ret = deflate(&zs, Z_FINISH);
if (outstring.size() < zs.total_out)
{
// append the block to the output string
outstring.append(outbuffer, zs.total_out - outstring.size());
}
} while(ret == Z_OK);
deflateEnd(&zs);
if(ret != Z_STREAM_END) // an error occurred that was not EOF
{
std::ostringstream oss;
oss << "Exception during zlib compression: (" << ret << ") " << zs.msg;
std::cout << oss.str();
}
return outstring;
}
I know, I know, that function needs work, I just C&P'd from somewhere to try it out.
But the thing is this:
std::cout << "DEBUG" << std::endl; is never called. The compiler says that the seg fault is coming from here:
std::string zlib_compress(const std::string& str)
> {
But why...? It was working earlier. I just don't know what went wrong!
Edit: Debugger output.
#0 00000000 0x00402cbb in __chkstk_ms() (??:??)
#1 004013BE zlib_compress(str=...) (C:\Users\***\Documents\Work\Programming\Compressor\z.cpp:5)
#2 00401DDA _fu15___ZSt4cout() (C:\Users\***\Documents\Work\Programming\Compressor\main.cpp:80)
char outbuffer[1073741824];
That's too large to put on the stack
You are taking a constant reference to a string as a parameter in your zlib_compress - you need to make sure that memory is available (whatever is returned from your readfile) in your zlib_compress. It would be good if you can share the prototype of your readFile function too.