Why does the console overwrite output? - c++

I'm at the start of writing a csv-file parser for a file with around 8000 Ids. When running, after around half the Ids are read and printed, the Clion console starts overwriting the first outputs so that at the end of running the first Id in my consoles output is the 2626th instead of the first. What in my code is responsible for this?
When printing every read character before the switch starts, the output is complete. It also works with a smaller amount of Ids, when i shorten the amount in the csv to around 6000.
int main() {
string buffer;
char zeichen;
ifstream eingabe;
eingabe.open("../lib/Daten.csv");
int zustand=0;//0=Token, 1=Werte
if(eingabe){
while(!eingabe.eof()) {
eingabe.get(zeichen);
//cout<<zeichen; // with only this it works
switch(zeichen){
case';':
if(zustand==0){
cout<<"Token: "<<buffer<<"; ";
}
else if(zustand==1){
cout<<"Wert: "<<buffer<<"; ";
}
buffer="";
break;
case'\n':
if(zustand==0){
zustand=1;
cout<<"Token: "<<buffer<<endl;
}
else if(zustand==1){
cout<<"Wert: "<<buffer<<endl;
}
buffer="";
break;
default:
buffer+=zeichen;
break;
}
}
}
eingabe.close();
return 0;
}

Answered by all the helpful people in the comments. It seems to be connected to Clion

Related

How to make program working properly after using goto?

After any selection, I want to ask the user if they want to use the program again, or quit. But if y is inputted code doesn't work properly again. I tried the other solutions like clearing memory etc but I am not very experienced so I don't know what I am doing. Also sorry about my language. This is a part of my code. I have 13 different selections each of them work the same
char str[100];
int selection;
char selection2;
int i;
begin:
printf("Welcome to the Character/String Specification program\n");
printf("Please enter whatever you want \n");
scanf(" %s", str);
printf("\nSelect the specification you want\n");
printf("1) is your input a letter?\n");
printf("2) is your input a whitespace?\n");
printf("3) is your input a decimal digit?\n");
printf("4) is your input a hexadecimal digit?\n");
printf("5) is your input an upper-case letter?\n");
printf("6) is your input a lower-case letter?\n");
printf("7) is your input a letter or a decimal digit?\n");
printf("8) is your input a control character?(ACSII 0..31 and 127)\n");
printf("9) is your input a not a letter, digit, whitespace, or invisible control character?\n");
printf("10)is your input a printable (ASCIII ' '..'~')\n");
printf("11)is your input have a graphical representation\n");
printf("12)Do you want to see your input as all upper characters?\n");
printf("13)Do you want to see your input as all lower characters?\n\n");
scanf(" %d",&selection);
printf("\n");
while(true)
{
if(selection == 1)
{
while(str[i])
{
if(isalpha(str[i]))
{
printf("%c is an alphabet\n",str[i]);
}
else
{
printf("%c is not an alphabet\n",str[i]);
}
i++;
}
printf("Do you want to go back to the start point? (y) for yes,(n) for no\n");
scanf(" %c",&selection2);
if(selection2=='y')
{
goto begin;
}
else if(selection2=='n')
{
printf("Goodbye\n");
break;
}
instead of using goto, I would do something like this:
int value = 1;
do {
//enter your code here
if(selection2=='n')
{
printf("Goodbye\n");
value = 0;
break;
}
} while(value)
This will cause the code to run at least once and continue running based on user input.
Goto is not the best practice as it makes it harder to read.

How to make this C++ Program more robust?

Sorry for the vague title but i really do not know how to describe the problem concisely..and the following is the simple codes:
#include <iostream>
using namespace std;
bool func(int a,char c,int b,int& result)
{
switch(c)
{
case '-':
result=a-b;
break;
case '+':
result=a+b;
break;
default:
return false;
}
return true;
}
int main()
{
cout<<"Usage:A {+|-} B"<<endl;
while(true)
{
int a,b,result;
char c;
cin>>a>>c>>b;
if(func(a,c,b,result))
{
cout<<result<<endl;
}
else
{
cout<<"Input Error!"<<endl;
}
}
return 0;
}
The right method to use the program is to input A {+|-} B.
For example,you can input 1[SPACE]+[SPACE]2[ENTER](which I mean "1 + 2" and then press ENTER) then it will spit out "3" for me.For the purpose of making the program more robust,I try to input 1[SPACE]+[SPACE]2[SPACE]+[ENTER] It just give me many "2" printed on the shell.Is there anyone who could tell me how to fix the bug?Many thanks!
PS:The codes is available at github:bug0x001.cpp
You fail to check if the input was read correctly. That's the first thing to do in a robust program. Also, if it failed, you should fix the input source. The endless stream of 2 is caused by a broken cin.
if( cin>>a>>c>>b &&
func(a,c,b,result))
{
}
else
{
cin.reset();
}
Your problem is that you are trying to get ints and char with cin, this is ok if you need that exact input, but crash when reading strange things (like a letter as int), as it reads garbage
The best solution (for me) is to read everything as a string (check cin.getline and stuff like that), then you "parse" the input as you whant, for example:
if you read "19+ 32 3" you can "easily" eliminate all spaces and split by any non numeric symbol, getting 3 strings: s1="19",s2="+" and s3="323", then you just parse each string as int (or whatever you need) and the symbol as char or whatever.
If you find anythng weird, you can try to understand it, eliminate it or just show an input error.
Is more complex than doing a cin.reset after testing, but allow you to "understand" more types of data input

Strange behaviour when reading in int from STDIN

Suppose we have a menu which presents the user with some options:
Welcome:
1) Do something
2) Do something else
3) Do something cool
4) Quit
The user can press 1 - 4 and then the enter key. The program performs this operation and then presents the menu back to the user. An invalid option should just display the menu again.
I have the following main() method:
int main()
{
while (true)
switch (menu())
{
case 1:
doSomething();
break;
case 2:
doSomethingElse();
break;
case 3:
doSomethingCool();
break;
case 4:
return 0;
default:
continue;
}
}
and the follwing menu():
int menu()
{
cout << "Welcome:" << endl
<< "1: Do something" << endl
<< "2: Do something else" << endl
<< "3: Do something cool" << endl
<< "4: Quit" << endl;
int result = 0;
scanf("%d", &result);
return result;
}
Entering numerical types works great. Entering 1 - 4 causes the program to perform the desired action, and afterwards the menu is displayed again. Entering a number outside this range such as -1 or 12 will display the menu again as expected.
However, entering something like 'q' will simply cause the menu to display over and over again infinitely, without even stopping to get the user input.
I don't understand how this could possibly be happening. Clearly, menu() is being called as the menu is displayed over and over again, however scanf() is part of menu(), so I don't understand how the program gets into this error state where the user is not prompted for their input.
I originally had cin >> result which did exactly the same thing.
Edit: There appears to be a related question, however the original source code has disappeared from pastebin and one of the answers links to an article which apparently once explained why this is happening, but is now a dead link. Maybe someone can reply with why this is happening rather than linking? :)
Edit: Using this example, here is how I solved the problem:
int getNumericalInput()
{
string input = "";
int result;
while (true)
{
getline(cin, input);
stringstream sStr(input);
if (sStr >> result)
return result;
cout << "Invalid Input. Try again: ";
}
}
and I simply replaced
int result = 0;
scanf("%d", &result);
with
int result = getNumericalInput();
When you try to convert the non-numeric input to a number, it fails and (the important part) leaves that data in the input buffer, so the next time you try to read an int, it's still there waiting, and fails again -- and again, and again, forever.
There are two basic ways to avoid this. The one I prefer is to read a string of data, then convert from that to a number and take the appropriate action. Typically you'll use std::getline to read all the data up to the new-line, and then attempt to convert it. Since it will read whatever data is waiting, you'll never get junk "stuck" in the input.
The alternative is (especially if a conversion fails) to use std::ignore to read data from the input up to (typically) the next new-line.
1) Say this to yourself 1000 times, or until you fall asleep:
I will never ever ever use I/O functions without checking the return value.
2) Repeat the above 50 times.
3) Re-read your code: Are you checking the result of scanf? What happens when scanf cannot convert the input into the desired format? How would you go about learning such information if you didn't know it? (Four letters come to mind.)
I would also question why you'd use scanf rather than the more appropriate iostreams operation, but that would suffer from exactly the same problem.
You need to verify if the read succeeded. Hint: it did not. Always test after reading that you successfully read the input:
if (std::cin >> result) { ... }
if (scanf("%d", result) == 1) { ... }
In C++ the failed state is sticky and stays around until it gets clear()ed. As long as the stream is in failed state it won't do anything useful. In either case, you want to ignore() the bad character or fgetc() it. Note, that failure may be due to having reached the end of the stream in which case eof() is set or EOF is returned for iostream or stdio, respectively.

How do I use a loop to display a menu and re-prompt for input?

I want to have a menu display that accepts user input. However, I want the user to be able to go back to the beginning of the menu to reselect options.
while(end != 1) {
display menu options
prompt user for input
if(input == x) {
do this
}
else
do that
}
then, i want it to skip back up to the beginning of the loop and ask the question over again. Howcan I do this without creating an infinite loop of the menu printing across the screen?
Unfortunately you didn't really show the code you are using but rather some pseudo code. Thus, it is hard to tell what you are actually trying to do. From the description of your problem and your pseudo code I suspect, however, that the root of the problem is that you don't check your inputs and don't restore the stream to a reasonably good state! To read the menu selection you probably want to use code akin to this:
int choice(0);
if (std::cin >> choice) {
deal with the choice of the menu here
}
else if (std::cin.eof()) {
// we failed because there is no further input: bail out!
return;
}
else {
std::string line;
std::cin.clear();
if (std::getline(std::cin, line)) {
std::cout << "the line '" << line << "' couldn't be procssed (ignored)\n";
}
else {
throw std::runtime_error("this place should never be reached! giving up");
}
}
This is just a rough layout of how the input would basically look like. It would probably be encapsulated into a function (in which case you'd want to bail out of from a closed input somewhat differently, possibly using an exception or a special return value). The main part of his is to
restore the stream back to good state using std::isteam::clear()
skip over the bad input, in this case using std::getline() with a std::string; you could also just std::istream::ignore() the remainder of the line
There may be other problems with your menu but without seeing concrete code I'd think it is hard to tell what the concrete problems are.
Instead of using a while, consider using a function, so you can call it where you need it:
void f()
{
if(end != 1) {
display menu options
prompt user for input
if(input == x) {
do this
f();
}
else{
do that
f();
}
}
}
I am not sure what your looking for either but this is some rough code of a menu
while(1){
cout<<"******* Menu ********\n";
cout<<"-- Selections Below --\n\n";
cout<<"1) Choice 1\n";
cout<<"2) Choice 2\n";
cout<<"3) Choice 3\n";
cout<<"4) Choice 4\n";
cout<<"5) Exit\n";
cout<<"Enter your choice (1,2,3,4, or 5): ";
cin>>choice;
cin.ignore();
switch(choice){
case 1 :
// Code for whatever you need here
break;
case 2 :
// Code for whatever you need here
break;
case 3 :
// Code for whatever you need here
break;
case 4 :
// Code for whatever you need here
break;
case 5 :
return 0;
}

cin.get() is non-blocking

I have the same problem as mentioned in the linked question. The console window (in VS 2010) disappears immediately after running the program. I use a cin.get(); at the end of the main function, but the problem still remains. Any idea about the possible reason? You can check out the code in main:
int main()
{
const int arraysize = 10;
int order;
int counter;
int a[arraysize] = {2,6,4,45,32,12,7,33,23,98};
cout<<"Enter 1 to sort in ascending order\n"
<<"Enter 2 to sort in descending order\n";
cin>>order;
cout<<"Data items in original order\n";
for(counter=0;counter<arraysize;counter++){
cout<<setw(4)<<a[counter];
}
switch (order){
case 1: cout<<"\nData items in ascending order\n";
selectionSort(a, arraysize, ascending);
break;
case 2: cout<<"\nData items in descending order\n";
selectionSort(a, arraysize, descending);
break;
default: return 0;
}
for(counter=0;counter<arraysize;counter++){
cout<<setw(4)<<a[counter];
}
cout<<endl;
cin.get();
return 0;
}
link : C++ on Windows - the console window just flashes and disappears. What's going on?
So when using cin.get() after cin, you should always remember to add cin.ignore() between them .
cin>>order;
cin.ignore();
/*
other codes here
*/
cin.get();
It is mainly because the CIN will ignore the whitespace in the buffer, so after cin>>order, there is a "newline"(\n) in the buffer, then your cin.get just read that \n, then you program successfully executed and return. The cin.ignore() will ignore previous input in the buffer. This really help!
I am a student in China. Your question is the first one I can answer here. I once had the same trouble as you. I hope this helps you.
Ignore my poor english and thank you.
My guess is that
default: return 0;
get executed.
EDIT:
You're right, that's not the issue. Read this.
The quick fix is:
cout<<endl;
cin.ignore(); // <---- ignore previous input in the buffer
cin.get();
But you might want to read the article for further info on the behavior.
I bet you hit the default switch label (return 0;). This bypasses cin.get() - you need one cin.get() per return statement.
Probably your cin.get() is reading the newline which terminated your order input? You could try calling cin.get() twice.