Getting unusual output in simple file handling program - c++

What is the problem with this code?
I am trying to write to a binary files MCQ type question
e.g, Question: If a computer provides database services to other, then it will be known as ? 1.Web server 2.Application 3.Database server 4.FTP server
ID: 1
Answer: 3
.
.
.
But I am getting unusual output.
Please have a look at the code I have provided comments.
The program asks for questions and write it to a binary file.
The id is automatically incremented, the question and the answer is asked from the user.
If the question is "x" then the program stops and if its anything else it asks for the answer and set all three id, question, answer to a temporary object and then write it to the file.
The program work fine for the first question & answer and then directly asks for the answer for the second answer without asking for the second question.
#include <iostream>
#include <fstream>
#include<string.h>
#include<conio.h>
using namespace std;
class questions{ //start of class
//private members
int id; //identification number for question ( 1,2,3,....)
char ques[100]; //question
int ans; //answer (1,2,3,4) MCQ
public: //public members
void displayques() //displays question
{
cout<<ques; //the same
}
int getans() //returns answer
{
return ans; //the same
}
int getid() //returns id
{
return id; //the same
}
void setques(char q[]) //set the given string in parameter to the question.
{
strcpy(ques,q);
}
void setid(int i) //set the given int as id
{
id=i;
}
void setans(int a) //set the given int as answer
{
ans=a;
}
}; //end of class questions
int main() //start of main
{
questions quesobj; //create an object of class questions
ofstream quesfile; //creates and object of class ofstream
quesfile.open("questions.dat",ios::out|ios::binary); //opens questions.dar in output mode as binary with the object quesfile of ofstream
char ask='y'; //to stop the process when its changed to n
char tempques[100]; //to temporarily store the question
int tempid=1; //to temporarily store the id, initially at 1, later is incremented
int tempans; //to temporarily store the answer
while(ask!='n') //runs upto the the point when use wants to escape the loop
{
cout<<"Question? or enter x to stop"<<endl; //asks the questions also ask if user want to escape can enter x
gets(tempques); //gets the question in temporary variable
cout<<"Question registered"<<endl; //shows question is ready to be written
if(strcmp(tempques,"x")==0) //if user enter the question as x
{
ask='n'; //sets ask to n which will end the loop
}
else //if user enters something else than x, it is considered the question
{
cout<<"Answer:"<<endl; //ask for the answer
cin>>tempans; //stores answer in temporary variable
cout<<"Answer registered"<<endl; //shows answer is ready to be written
quesobj.setid(tempid); //sets id to the temp object of the class questions
quesobj.setques(tempques); //sets question to the temp object of the class questions
quesobj.setans(tempans); //sets answer to the temp object of the class questions
quesfile.write((char *)&quesobj, sizeof(quesobj)); //write the temp object of class questions to the binary file
tempid++; //tempid is incremented for the next loop so that every question has its own id
}
} //end of while
quesfile.close(); // closes the file using the object of ofstream
}
OUTPUT:
Question? or enter x to stop
This is my first question?
Question registered
Answer:
2
Answer registered
Question? or enter x to stop
Question registered
Answer:
_

As suggested in the comments,
you should not mix C and C++ style IO.
As your code was not compiling on my system, I have cleaned your code a bit. I have tested it and its now working perfectly.
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
int string_to_int(const string& str)
{
stringstream ss(str);
int str_int;
ss >> str_int;
return str_int;
}
class Question
{
int id;
string question_string;
int answer;
public:
void displayQuestion()
{
cout << question_string;
}
int getAnswer()
{
return answer;
}
int getId()
{
return id;
}
void setQuestion ( const string& question_string_)
{
question_string = question_string_;
}
void setId ( int id_ )
{
id = id_;
}
void setAnswer ( int answer_ )
{
answer = answer_;
}
};
int main()
{
Question question;
ofstream question_file;
question_file.open ( "questions.dat", ios::out | ios::binary );
char option = 'y';
string temp_question;
int temp_id =1;
int temp_answer;
while ( option != 'n' )
{
cout << "Question? or enter 'x' to stop" << endl;
getline(cin, temp_question);
cout << "Question registered" << endl;
if (temp_question == "x")
{
option = 'n';
}
else
{
cout << "Answer? :" << endl;
string temp_answer_string;
getline(cin, temp_answer_string);
temp_answer = string_to_int(temp_answer_string);
cout << "Answer registered" << endl;
question.setId ( temp_id );
question.setQuestion ( temp_question );
question.setAnswer ( temp_answer );
question_file.write ( ( char* ) &question, sizeof ( question ) );
temp_id++;
}
}
question_file.close();
}

Related

No error in code but the data is not being written in output txt [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I tried to write a code for my assignment. It is not showing any error but when I read input from the file, save them in array of object and then, I'm trying to put write values to an output file. the data is of that object which I want to write but nothing is being written in the output txt. I cant find the problem.
The input txt file format
2
//number of students
3
// number of grades (per student)
Student1 99 87 90
// / name grade grade grade
Student2 50 67 95
Code is written below
#include <iostream>
#include <conio.h>
#include <string>
#include <fstream>
using namespace std;
class Student
{
private:
string name;
int grade1;
int grade2;
int grade3;
float avg;
public:
Student()
{
name = "\0";
grade1 = grade2 = grade3 = avg = 0;
}
void setname(string Name)
{
name = Name;
}
void setgrade1(int num)
{
grade1 = num;
}
void setgrade2(int num)
{
grade2 = num;
}
void setgrade3(int num)
{
grade3 = num;
}
void AVG()
{
avg = (grade1 + grade2 + grade3) / 3;
}
float getAVG()
{
return avg;
}
string getName()
{
return name;
}
};
int main()
{
char ch = '\0';
char pre = '\0';
Student S[3];
int totalstudents = 0;
int totalgrades = 0;
cout << "Enter file name including " ", e.g \"myFile.txt\" :" << endl;
string file;
cin >> file;
fstream myFile;
int loop = 0;
int loop2 = 0;
myFile.open(file);
{
while (myFile.get(ch))
{
if (loop != 1)
{
myFile >> totalstudents >> totalgrades;
loop++;
}
string namE;
int g1, g2, g3;
myFile >> namE >> g1 >> g2 >> g3;
S[loop2].setname(namE);
S[loop2].setgrade1(g1);
S[loop2].setgrade2(g2);
S[loop2].setgrade3(g3);
S[loop2].AVG();
loop2++;
if (loop2 == totalstudents)
break;
}
}
myFile.close();
fstream myFile2;
myFile2.open("fout.txt");
{
for (int loop = 0; loop < totalstudents; loop++)
{
myFile << S[loop].getName() << "\t" << S[loop].getAVG() << endl;
}
};
myFile2.close();
_getch();
}
while (myFile.get(ch))
get() reads one character from the file. It is has now been read, never to be read again. Unfortunately, the subsequent code still expects the initial contents to be there, which it expects to read from this point on.
This is the fundamental logical error that fails to produce the expected results. You will need to completely redesign the input reading part of the problem, in order to fix the incorrect logic.
For some reason the current logic crams the code that reads the initial totalstudents and totalgrades as part of the loop that reads each student's data. This unnecessarily complicates the logic. Simply reading this, first, followed by a single loop to read each students data, should be sufficient. Unfortunately there are additional fundamental issues with the shown code that will require a more complete overhaul, in order to fix them properly.
The shown code can only handle no more than three students' data, and is hardcoded to handle exactly three grades for each student.
It seems clear to be from the description of the assignment that your program should handle any number of students, 2 students, 3 students, or a 100 students; and any number of grades per student, and not always three grades exactly. Otherwise there would be no reason, whatsoever, to provide these values in the input data.
Unfortunately, this is not possible using the current program's class, and logic, and this will also need to be addressed as well.

How do I change my classes private attribute value? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
If I use a setter, it should then change my private classes attribute's value right? However that's not the case, it's just giving me the default value of the private attribute when I use the setter. I am finding the distance travelled value with a getter.
Player.h
#pragma once
class Player
{
public:
void setForestDistanceTravelled(int amount);
int getForestDistanceTravelled();
private:
unsigned short int forestDistanceTravelled = 0;
};
Player.cpp
#include "Player.h"
void Player::setForestDistanceTravelled(int amount)
{
forestDistanceTravelled += amount;
}
int Player::getForestDistanceTravelled()
{
return forestDistanceTravelled;
}
forest.cpp
void welcomeToForest()
{
Forest forest;
Player player;
std::string userInput;
system("cls");
std::cout << "Your current distance is: " << player.getForestDistanceTravelled();
std::cin >> userInput;
if (userInput == "1")
{
unsigned short int playerDist = 0;
system("cls");
playerDist = forestDistanceRand();
player.setForestDistanceTravelled(playerDist);
welcomeToForest();
}
}
As Yksisarvinen states in the comments, the problem lays in new instances of the Player object spawning again and again with each recursion of welcomeToForest().
You just want to isolate the recursive bit of that function into its own function, that accepts the Player object as an outside parameter.
Something like below should work, whilst preserving the recursive logic of the program:
void recursiveBit(Player& player_)
{
std::string userInput;
system("cls");
std::cout << "Your current distance is: "
<< player.getForestDistanceTravelled();
std::cin >> userInput;
if (userInput == "1")
{
unsigned short int playerDist = 0;
system("cls");
playerDist = forestDistanceRand();
player_.setForestDistanceTravelled(playerDist);
recursiveBit(player_);
}
}
void welcomeToForest()
{
Forest forest;
Player player;
recursiveBit(player);
}

ifstream getline - Reading txt File to an array of objects, but it's only reading the first line?

I'm writing a beginner program that takes a text file of 10 trivia questions and answers, reads the file, puts the questions and answers into an array, and then uses the questions for a trivia game.
Currently, I'm having an issue reading the file into the array. Only the first line of the file is being read.
I'm new to debugging, but I tried to rewrite the program with Vectors and had the same issue.
Here is the trivia file (the number at the end of the answers is the correct answer):
The Gettysburg Address
The US Declaration of Independence
The Magna Carta
The US Bill of Rights
2
(2) Who said "A billion dollars isn't worth what it used to be"?
J. Paul Getty
Bill Gates
Warren Buffet
Henry Ford
1
(3) What number does "giga" stand for?
One thousand
One million
One billion
One trillion
3
(4) What number is 1 followed by 100 zeros?
A quintillion
A googol
A moogle
A septaquintillion
2
(5) Which of the planets is closest in size to our moon?
Mercury
Venus
Mars
Jupiter
1
(6) What do you call a group of geese on the ground?
skein
pack
huddle
gaggle
4
(7) What do you call a group of geese in the air?
skein
pack
huddle
gaggle
1
(8) Talk show host Jerry Springer was the mayor of this city.
Chicago
Indianapolis
Cincinnati
Houston
3
(9) On a standard telephone keypad, the letters T, U, and V are matched to what number?
5
6
7
8
4
(10) Crickets hear through this part of their bodies.
Head
Knees
Ears
Tail
2
Here is my program currently:
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;
//Question class
class Question{
private:
string triviaQuestion;
string answer1;
string answer2;
string answer3;
string answer4;
int correctAnswer; //1,2,3 or 4
public:
Question();
//mutator functions
void setTriviaQuestion(string);
void setAnswer1(string);
void setAnswer2(string);
void setAnswer3(string);
void setAnswer4(string);
void setCorrectAnswer(int);
//accessor functions
string getTriviaQuestion();
string getAnswer1();
string getAnswer2();
string getAnswer3();
string getAnswer4();
int getCorrectAnswer();
};
//Question class member functions
Question::Question(){
//initialize member variables
correctAnswer = 0;
triviaQuestion = " ";
answer1 = " ";
answer2 = " ";
answer3 = " ";
answer4 = " ";
}
void Question::setTriviaQuestion(string question){
triviaQuestion = question;
}
void Question::setAnswer1(string option) {
answer1 = option;
}
void Question::setAnswer2(string option) {
answer2 = option;
}
void Question::setAnswer3(string option) {
answer3 = option;
}
void Question::setAnswer4(string option) {
answer4 = option;
}
void Question::setCorrectAnswer(int number) {
correctAnswer = number;
}
string Question::getTriviaQuestion(){
return triviaQuestion;
}
string Question::getAnswer1() {
return answer1;
}
string Question::getAnswer2() {
return answer2;
}
string Question::getAnswer3() {
return answer3;
}
string Question::getAnswer4() {
return answer4;
}
int Question::getCorrectAnswer() {
return correctAnswer;
}
//main function
int main() {
//variables
int playerOneScore = 0;
int playerTwoScore = 0;
string holder = " ";
const int ARRAY_SIZE = 10;
Question triviaInfo[ARRAY_SIZE];
//check for a file's existence before opening it
ifstream dataFile;
dataFile.open("trivia.txt");
if (dataFile.fail()){
//The file does not exist
cout << "ERROR: Cannot open trivia File.";
}
else{
//the file already exists
//get the data from the file and put into the Question array
//for each element of the array
int fiveLineCounter = 0;
int arrayCounter = 0;
while (getline(dataFile, holder)){
cout << holder << endl; // test to see what's being entered
if (fiveLineCounter == 0){
triviaInfo[arrayCounter].setTriviaQuestion(holder);
fiveLineCounter++;
}
if (fiveLineCounter == 1){
triviaInfo[arrayCounter].setAnswer1(holder);
fiveLineCounter++;
}
if (fiveLineCounter ==2){
triviaInfo[arrayCounter].setAnswer2(holder);
fiveLineCounter++;
}
if (fiveLineCounter == 3){
triviaInfo[arrayCounter].setAnswer3(holder);
fiveLineCounter++;
}
if (fiveLineCounter == 4){
triviaInfo[arrayCounter].setAnswer4(holder);
fiveLineCounter++;
}
if (fiveLineCounter == 5){
triviaInfo[arrayCounter].setCorrectAnswer(stoi(holder));
arrayCounter++;
fiveLineCounter = 0;
}
}
}
return 0;
}
When I run the program, this is the current output:
(1) What famous document begins: "When in the course of human events..."?
Process finished with exit code 0
Would really appreciate any help or pointers on how to fix this.
Thank you!
fiveLineCounter starts as zero. So if (fiveLineCounter == 0){ check is true, the code calls setTriviaQuestion(holder) and increments fiveLineCounter; it's now 1.
Then the next check if (fiveLineCounter == 1){ is true, so the code calls setAnswer1(holder) (with the same line in holder) and and increments fiveLineCounter; it's now 2.
Then the next check if (fiveLineCounter == 2){ is true, ...
This continues until setCorrectAnswer(stoi(holder)). Whereby stoi(holder) throws an exception, because the contents of holder (still the first line of the file) can't be parsed as an integer.

Whenever i use cin and use spaces in the string, why does it just skip through the whole thing? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I made a program that should take input print it. Then run a simple addition thing but when i use spaces in the input it skips through the addition. I do not know what the problem is.
this is the class stuff
#include <iostream>
#include <string>
using namespace std;
class Cheese {
private:
string name;
public:
void setName(string x){
cin >> x;
x = name;
}
string getName(){
return name;
}
void print(){
cout << name << endl;
}
};
this is the main stuff
int main()
{
string h;
Cheese hole;
hole.setName(h);
hole.getName();
hole.print();
this part is getting skipped through without letting me input
int x = 5;
int y = 16;
cout << x+y;
num(x);
int a;
int b;
int c;
cout << "Type in a number and press enter.";
cin >> a;
cout << "Repeat.";
cin >> b;
c = a+b;
cout << c << endl;
if(c <= 21){
cout << "Good job!";
}
else {
cout << "You fail!";
}
return 0;
}
I suggest you divide the responsibilities a little differently. The Cheese class's setName function should simply take a string and set the instance's member variable to the given argument.
Then your program can read from standard input and populate a string within main, and pass that string to setName.
To be more concrete:
class Cheese {
private:
string name;
public:
void setName(const string& x){
// change this code to set the 'name' member variable
}
[...]
};
And the main becomes:
int main()
{
string h;
Cheese hole;
std::string input_name;
cout << "Type a name and press enter.";
cin >> input_name; // Will read up to first whitespace character.
hole.setName(input_name);
hole.getName(); // this is a no-op: compiler may warn of unused return value
hole.print();
In general, reading standard input as part of a class's interface is a bad idea, because it makes it hard to re-use that class in the future (for example, with programs that take input from a file instead of from a human at a console).
The input that you pass to cin input stream skips any white space, Tab space or newline. If you wish to input string then you can use cin.getline(string s). The input after the white space gets passed to next waiting cin, as the next cin accepts integer and it get a character string it skips that. Thus when enter a string with white spaces the program skips the remaining part.

I have an invalid initialization of reference of type int& from expression of type in passing argument 1

Im trying to lean structures and I think I am doing something wrong when I use the structure and trying to call it into a function.
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
//Structure
struct Inventory
{
int NumberPartsBin;
};
//Function Prototypes.
void choiceMenu();
void AddParts(int &);
void RemoveParts(int &);
int main()
{
char Election;
int choice;
Inventory Parts = {10};
const int Valve_Choice = 1,
Quit_Choice = 2;
I am trying to to resolve this problem with one item, but I will use arrays for 10 items.
do {
choiceMenu();
cin>> choice;
if (choice >= Valve_Choice & choice <= Quit_Choice)
{
switch(choice){
case Valve_Choice:
cout<<"Enter A for Add Parts or R to Romove Parts";
cin >> Election;
if (Election=='A')
{
AddParts(Parts);// My problem is here
}
if else (Election =='R'){
RemoveParts(Parts);}
else{
cout << "Invalid Entry. Try Again";
cin >> Election; }
break;
case Quit_Choice:
cout<<"Program Ending";
return;
else
{
cout<<"Enter a valid choice!!;
cin >> choice;
}
}
}
while (choice >= Valve_Choice & choice < Quit_Choice);
system("pause");
return 0;
// Bin Choice
void choiceMenu()
{
// We use ofstream to create and write on a text file.
ofstream outputFile;
outputFile.open("C:\\Users\\Alexander MR\\Desktop\\CompanyABCPayRoll.txt");
// The headed of the document.
outputFile << " Inventoy\n";
outputFile << " = = = = = = = = \n";
outputFile << " *Choose the part of your preference.\n";
outputFile << " 1. valves = " << Parts.NumberPartsBin << endl;
outputFile << " 11. Choose 2 to quit the Program" << endl;
outputFile.close();
}
I am not sure of my function either.
my function to add parts
void AddParts(int &Parts1)
{
int Enter1;
Parts1.NumberPartsBin = Parts1.NumberPartsBin + Enter1;
}
My function to remove parts
void RemoveParts(int &Parts2)
{
int Enter2;
Parts2.NumberPartsBin = Parts2.NumberPartsBin - Enter2;
}
Reading the question with only parts of the code formatted is quite hard. The first thing I saw was:
void RemoveParts( int &Parts2 ) {
int Enter2;
Parts2.NumberPartsBin = Parts2.NumberPartsBin - Enter2;
}
This makes no sense at all. If Parts2 is an int, then you will never be able to say Parts2.NumberPartsBin. The second thing is int Enter2;. You never give it a value, but in the next line you want to subtract it from something‽
I'm guessing (at least with this function) that you are trying to do something like this:
void RemoveParts( Inventory& inventoryItem, int amountOfParts ) { // inventoryItem is passed by reference, amountOfParts is passed by value
inventoryItem.NumberPartsBin = inventoryItem.NumberPartsBin - amountOfParts;
}
Looking at your code, I'm guessing you're quite new to all of this. I'm no guru, but please:
Capitalize class/struct names and start variable names with a lowercase. ( like parts or election)
If you want to change the value that comes into a function, pass it by reference, but if it is something like an int or a char, simply pass it by value.
p.s. it's if, else if, else and not if else which will otherwise be the next error in your code.