-
July 27th, 2010, 02:06 AM
#1
why is it skipping lines?
I have a function called addChecksum that is called from a switch statement. The function is to ask for a file path to a file, then to open the file. But if it doesn't open, then it should take you back to the menu. Right now, it runs through the entire function without giving me a chance to enter the file path. I don't understand why. Here is my code
Code:
#include "stdafx.h"
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>
using namespace std;
void selection();
void addChecksum();
void runChecksum();
int main()
{
selection();
system("pause");
return 0;
}
void selection()
{
char choice;
cout << "Please Select: " << endl;
cout << " A) Add checksum to specified file" << endl;
cout << " B) Verify integrity of specified file" << endl;
cout << " Q) Quit" << endl;
cin >> choice;
cout << endl;
switch (choice)
{
case 'A':
addChecksum();
break;
case 'a':
addChecksum();
break;
case 'B':
runChecksum();
break;
case 'b':
runChecksum();
break;
case 'Q':
return;
case 'q':
return;
default:
cout << "Your choice did not match any of the menu options." << endl;
}
}
void addChecksum()
{
string inputFileName;
ifstream inputFile;
string line;
cout << "Specify the file path: ";
getline(cin, inputFileName);
inputFile.open(inputFileName.c_str());
cout << endl;
while(!inputFile.is_open())
{
cout << "The file " << inputFileName << "could not be found or opened!" << endl;
selection();
}
}
void runChecksum()
{
string inputFileName;
ifstream inputFile;
string line;
int checksum;
checksum = 0;
while(!inputFile.is_open())
{
cout << "Specify the file path: " << inputFileName;
getline(cin, inputFileName);
inputFile.open(inputFileName.c_str());
}
cout << "File checksum = " << checksum << endl;
}
-
July 27th, 2010, 03:34 AM
#2
Re: why is it skipping lines?
Because you need to clear the cin buffer of invalid characters:
Code:
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>
#include <cctype> // for tolower
#include <limits> //for numeric_limits
using namespace std;
void selection();
void addChecksum();
void runChecksum();
int main()
{
selection();
// A more portable version of system("pause") is:
std::cout << "Press return to continue" << std::endl;
std::cin.get();
return 0;
}
void selection()
{
char choice;
cout << "Please Select: " << endl;
cout << " A) Add checksum to specified file" << endl;
cout << " B) Verify integrity of specified file" << endl;
cout << " Q) Quit" << endl;
cin >> choice;
cout << endl;
//Clear anything currently in the cin buffer
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
//You can reduce the size of your switch statement by using tolower.
[COLOR=Red]switch (tolower(choice))
{
case 'a':
addChecksum();
break;
case 'b':
runChecksum();
break;
case 'q':
return;
default:
cout << "Your choice did not match any of the menu options." << endl;
}
}
void addChecksum()
{
string inputFileName;
ifstream inputFile;
string line;
cout << "Specify the file path: ";
getline(cin, inputFileName);
inputFile.open(inputFileName.c_str());
cout << endl;
while(!inputFile.is_open())
{
cout << "The file " << inputFileName << "could not be found or opened!" << endl;
//You have a bug here. What if someone realises they don't
//want to load a file anymore, but want to quit instead?
//selection will keep being called even though the user is
// pressing 'q' because they have not entered a valid file name!
selection();
}
}
void runChecksum()
{
string inputFileName;
ifstream inputFile;
string line;
int checksum;
checksum = 0;
while(!inputFile.is_open())
{
cout << "Specify the file path: " << inputFileName;
getline(cin, inputFileName);
inputFile.open(inputFileName.c_str());
}
//I guess you are going to do your calulation here?
// ....
cout << "File checksum = " << checksum << endl;
}
Last edited by PredicateNormative; July 27th, 2010 at 03:37 AM.
Reason: Changed colour on font.
-
July 27th, 2010, 07:14 AM
#3
Re: why is it skipping lines?
You shouldn't keep calling functions recursively like that in this case. Set up a while loop instead.
-
July 27th, 2010, 08:15 AM
#4
Re: why is it skipping lines?
The mixing of normal cin with getline() is a known complication. You can deal with it, though. There are hundreds of articles talking about the situation and its solutions. Try googling "skipped getline".
-
July 27th, 2010, 10:40 AM
#5
Re: why is it skipping lines?
The strange thing is that the code works just fine if I put it in a while loop. It does not skip the getline. So I googled it and added inputFile.clear(); but it still skips. I will keep googling. If you have another suggestion, I would be pleased to read it.
-
July 27th, 2010, 10:49 AM
#6
Re: why is it skipping lines?
Which webpage is telling you to use .clear()?
-
July 27th, 2010, 10:52 AM
#7
Re: why is it skipping lines?
I am reading a bunch of pages. Some say to clear the file stream, some say to use ignore, others have elaborate while statements that have stuff to do with using the /n. I am still looking for the solution
-
July 27th, 2010, 10:55 AM
#8
Re: why is it skipping lines?
The key thing is to put an ignore between a normal cin and a getline----but not put one between two getlines. This can cause some difficulties if you're accessing the same stream in multiple functions.
The approach I usually take is to use getline() for every line, and then parse the line separately if necessary using a stringstream. That gets around the whole issue.
-
July 27th, 2010, 10:58 AM
#9
Re: why is it skipping lines?
I have only been working with c++ for 5 weeks. I am researching ignore() and how to use it right now
-
July 27th, 2010, 11:03 AM
#10
Re: why is it skipping lines?
Originally Posted by CyberShot
The strange thing is that the code works just fine if I put it in a while loop.
The code you did post does the following:
selection calls addchecksum, which calls selection, which calls addchecksum, which calls selection, which calls addchecksum ...
A few of these, and your stack space gets exhausted. Imagine if your program was supposed to be run non-stop.
There is no need for recursion in such a simple program. So when you say "while loop", are you referring to the code you posted or different code?
Regards,
Paul McKenzie
-
July 27th, 2010, 11:26 AM
#11
Re: why is it skipping lines?
I am following an assignment posted by my instructor. I had to change to code in order to call the menu again if the input file could not be found. Before that I had the code in addChecksum like this
Code:
string inputFileName;
ifstream inputFile;
string line;
while(!inputFile.is_open())
{
cout << "Specify the file path: ";
getline(cin, inputFileName);
inputFile.open(inputFileName.c_str());
cout << endl;
}
with the getline(cin, inputFileName) in the while loop, there was no problem, the code worked as it should. Once I took it out of the while loop in order to recalll the menu if the opening of the file failed, that is when I got the problems. I just fixed it though by placing
cin.ignore();
just before my getline();
So now it is working. Thanks Lindley for your help
-
July 27th, 2010, 11:35 AM
#12
Re: why is it skipping lines?
You don't appear to be understanding Paul's objection. Your current code never allows any of these functions to return, so you just keep going deeper and deeper onto the stack. This will break things eventually.
In general, you should only be calling your menu from main(). You "get back to it" when necessary by returning from other functions to main in such a way that the program loops back to the selection() call.
-
July 27th, 2010, 11:38 AM
#13
Re: why is it skipping lines?
I think I see what you are saying. I am doing it this way because I can easily understand what is going on at my level of programming. To do it your way would take me much more time than I have because I would have to figure it out. The program only needs to work once
-
July 27th, 2010, 11:53 AM
#14
Re: why is it skipping lines?
Well, just don't learn the bad habit. Your next program should be designed to do things differently from the start.
-
July 27th, 2010, 12:08 PM
#15
Re: why is it skipping lines?
Originally Posted by CyberShot
I think I see what you are saying. I am doing it this way because I can easily understand what is going on at my level of programming. To do it your way would take me much more time than I have because I would have to figure it out. The program only needs to work once
Appearing to work and actually working are two different things. Unless you really understand recursion, its possible side effects and potential pitalls, you shouldn't be using it, especially when it isn't called for. In this case, its use is just plain wrong.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|