Reputation: 1
I am not sure where I put the char command declaration where I wont get a "Not defined in this scope" error and it will loop through accepting a new char command the next time the program loops.
I tried putting it inside of the do loop but then it said that char was not defined in that scope, I then put it right after the int main function and when entering A as a command it infinitely loops my add_entry function without allowing user input.
Do I have to pass by reference maybe? Or pass by value?
My file that holds all function definitions
#include "main.h"
using namespace std;
int syntax::add_entry()
{
cout << "Enter a concept name: ";
cin.get(name, SIZE);
cout << endl << "Enter an example of the syntax: ";
cin.get(example,SIZE);
cout << endl << "Enter a description of the syntax: ";
cin.get(desc,SIZE);
cout << endl << "Enter a difficulty rating from 1-10: ";
cin.get(diff,SIZE);
cout << endl << "Enter a usefulness rating from 1-10: ";
cin.get(use,SIZE);
//open and write to the file
ofstream myfile;
myfile.open("data.txt");
myfile << "Name: " << name << endl;
myfile << "Example of syntax: " << example << endl;
myfile << "Description of syntax: " << desc << endl;
myfile << "Difficulty rating from 1-10: " << diff << endl;
myfile << "Usefulness rating from 1-10: " << use << endl;
myfile.close();
return 0;
}
int syntax::display_entry()
{
ifstream myfile("data.txt");
/*
char name[SIZE];
char example[SIZE];
char desc[SIZE];
char diff[SIZE];
char use[SIZE];
*/
if(myfile.is_open())
{
while(myfile >> name >> example >> desc >> diff >> use)
{
std::cout << name << ", " << example << ", " << desc << ", " << diff << ", " << use;
}
myfile.close();
}else
cout << "File is not open" << endl;
std::cin.get();
return 0;
}
my main .cpp file
#include "main.h"
using namespace std;
int main()
{
char command;
syntax c;
do{
cout << "Welcome to the C++ concept syntax user database." << endl;
cout << "Choose one of the following commands: " << endl;
cout << endl << endl;
cout << "A) Add a new entry B) Display all entrys C) Search for difficulty D) Exit: ";
cin >> command;
cout << endl;
if(command == 'A' || command == 'a')
{
c.add_entry();
}
else if(command == 'B' || command == 'b')
{
c.display_entry();
}
else if(command == 'D' || command == 'd')
{
cout << "Quitting program, Thank you for using" << endl;
}
}while(command != 'D' || command != 'd');
return 0;
}
my .h file
#include <iostream>
#include <fstream>
#include <cstring>
#include <cctype>
using namespace std;
class syntax
{
public:
const static int SIZE = 50;
char name[SIZE];
char example[SIZE];
char desc[SIZE];
char diff[SIZE];
char use[SIZE];
int display_entry();
int add_entry();
private:
};
Upvotes: 0
Views: 59
Reputation: 15277
You need to read and understand about "formatted input" and "unformatted input". Please check here.
Formatted input is done using the extractor operator >>
. It reads characters from a stream and formats them to the expected variable type. If you write int x; std::cin >> x
and you enter the number 12, so the digits/characters '1' and '2', your input will be formatted / converted to an integer value 12.
It is important to understand that formatted input
This default behavior can be addapted by setting certain flags.
Now, if we look at "unformatted input" functions, like get, it will read all kind of characters, including spaces and so on until it hits the specified delimiter, which is '\n' per default. For the get
function, the delimiter '\n' will not be extracted. So, it is still in the stream. This is in contrast to the getline
function which would extract the '\n' from the stream (but not store it).
All this you can read in the linked description.
And now, the root cause for all you problems, is also written in the description:
If no characters were extracted, calls setstate(failbit)
Then, let us look on the order of events
std::cin
will do nothing, because the failbit of the stream is set.cin >> command;
will do nothing and will especially not modify the "command" variable. This will still contain an 'a'You have an additional bug in the "while" condition. This must be corrected to: ´while (command != 'D' && command != 'd');´
Now, what to do.
First, and very important, for any IO-function you need to check, if it worked or not. There are functions to read the iostate of the stream. But c++ makes life easier. The bool-operator and the not-operator are overwritten and will return state information. If you want to know, if any IO operation was successful, the you can write something like if (std::cin) ....
Very convenient. But must be used.
And since IO operations return mostly a reference to the stream for which they were called, you can write if (cin >> command) . . .
. This will first call the extraction operator. This will return a reference to the stream and for that you can use an if
statement, because of the overwritten bool-operator.
But how to overcome the nasty problem with the '\n' in the stream, which is often there? There are basically 2 functionalities:
I recommend to add one time cin >> std::ws;
at the top of your "add_entry" routine and then you must change all get
functions to getline
. If not, you would need to add std::ws
before each get
statement.
And again, for each IO function, check the status! For example if (!cin.getline(example, SIZE)) .... do something, show error
And in the future. For any transition from formatted to unformatted input, use std::ws
And, do never forget to read the documentation carefully.
Have fun!
Upvotes: 1