I'm having quite the issue trying to figure out why these code segments are printing the error message even when I have done cout statements within the block that should return true / not print that error message. Any ideas? I'm new here so please let me know if this isn't allowed. Thanks!
Use of function:
case 'a':
{
// Format: a ID credits GPA
// Adds a student with the given student ID (ID), number of
// credits (credits), and overall GPA (GPA) to the database.
// If the student is already in the database, an error
// message should be printed indicating this.
int credits = 0;
double gpa = 0;
cin >> studentID;
cin >> credits;
cin >> gpa;
// Adds the student and checks to see if the student was actually added
// or if there was an existing student with the specified ID
bool added = addStudent(studentID, credits, gpa);
if(added == false);
{
cout << "Student already exists in database, nothing changed." << endl;
// Still prints this when executed with valid
}
break;
}
Function for adding student to array:
bool addStudent (int id, int numCredits, double gpa) {
// Check to see if student exists
if (nextEntry != 0)
{
for (int x = 0; x < 7000; x++) {
Student tmp = studentRecords[x];
if (tmp.studentId == id)
{
return false;
cout << "hey" << endl;
}
}
}
// If student does not exist, add to records database
if (nextEntry != 7000)
{
studentRecords[nextEntry].studentId = id;
studentRecords[nextEntry].numCredits = numCredits;
studentRecords[nextEntry].gpa = gpa;
nextEntry++;
return true;
// confirmed I can get here
}
return false;
}
You have an extra ; after your if (added==false) statement. This will terminate the if statement and the code after will run regardless of the check.
Related
The program won't compile in Visual Studio Community, I have no idea why. I've looked into the function and can't seem to find an answer. Any help would be appreciated as this is for my module at university. I'm a little new to C++ but have some experience in other languages. I just can't seem to find how to get the program to run. I get the below error codes when compiling:
main.cpp: In function ‘void runGame(std::__cxx11::string*, std::__cxx11::string*, int)’:
main.cpp:115:53: error: cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’
to ‘std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}’
for argument ‘1’ to ‘std::__cxx11::string answersGiven(std::__cxx11::string*, std::__cxx11::string*, int, int)’
answersGiven(correctAns[0], wrongAns[0], max, max2);
Here is the Code:
#include<iostream>
#include<string>
using namespace std;
int inputCheck(string menu, int limit); // Validates User Input for topic and difficulty selection.
void runGame(string questions[], string answers[], int level); // Function runs game based on questions.
string modifyQuestion(string q, int mod); // Function modifies question based on difficulty level.
string answersGiven(string correct[], string wrong[], int maxC, int maxW);
int main() {
string questions[3][4] = { // 2D array storing answers. Each row stores a Country.
{ "England", "Wales", "France", "Germany" }, // Stores Europe Questions.
{ "Brazil", "Peru", "Argentina", "Columbia" }, // Stores Additional Questions.
{ "Q1", "Q2", "Q3", "Q4" } // Stores South American Questions.
};
string answers[3][4] = { // 2D array storing answers. Each row stores a city.
{"London", "Cardiff", "Paris", "Berlin"}, // Europe Answers.
{"Brasila", "Lima", "Buenos Aires", "Bogota"}, // South America Answers.
{ "A1", "A2", "A3", "A4" } // Stores additional answers.
};
string topics[3] = { "Capital Cities", "" };
char replay; // Variable to check if the user wants to continue playing.
do {
cout << "Please choose one topic for the quiz:\n";
int choice = inputCheck("1: Europe\n2: South America\n3: Testing", 3); // Gets topic choice via validation function.
cout << "\nNow Select a Difficulty:\n";
int difficulty = inputCheck("1: Easy\n2: Medium\n3: Hard", 3); // Gets difficulty choice via validation function.
choice--;
// run the game
runGame(questions[choice], answers[choice], difficulty);
// Checks if user wants to replay game.
cout << "Do you want to play again? Press (Y) to replay: ";
cin >> replay; // Grabs input from user.
replay = toupper(replay); // Sets data to upper case.
} while (replay == 'Y');
return 0;
}
int inputCheck(string menu, int limit) {
cout << menu << endl; // Presents menu of options.
int num; // Variable to store user's input.
cin >> num; // gets user's input.
while (cin.fail() || num < 1 || num > limit) {
cout << "Invalid Input..." << endl; // Outputs error message.
cout << menu << endl; // Presents menu again.
cin.clear(); // Clearsinput error glag.
cin.ignore(1000, '\n'); // Ignores previous inputted data.
cin >> num; // grabs input again.
}
return num;
}
void runGame(string questions[], string answers[], int level) {
string correctAns[] = {};
string wrongAns[] = {};
cin.ignore(1000, '\n'); // Ignore any trailing enter keys in input stream.
int lives = 3; // Stores the amount of users lives.
string answer; // Stores user's answer.
int count = 0; // Keeps track of the current question.
int score = 0; // Keeps track of user's score.
while (lives > 0 && count < 4) {
string question = questions[count]; // Gets current question from array.
// Modifying question if medium or hard difficulty selected.
if (level == 2) {
// Medium
question = modifyQuestion(question, 6);
}
else if (level == 3) {
// Hard
question = modifyQuestion(question, 2);
}
// Asking Question.
cout << "What is the capital city of " << question << endl; // Asks user the question.
getline(cin, answer); // Gets answer from user, includes answers that are more than one word.
answer[0] = toupper(answer[0]); // Converts first character to upper case.
int max = 0;
int max2 = 0;
if (answer == answers[count]) { // Checks user's answer against current answer.
cout << "Well Done! You've got one right" << endl; // Correct answer message.
count++; // Adds one to question counter.
score++; // Adds one to score.
correctAns[count] = answer;
max++;
}
else {
lives--; // Deducts one from lives.
cout << "Oops, Not quite right... You have " << lives << " lives remaining."; // Outputs incorrect message.
wrongAns[count] = answer;
max2++;
}
answersGiven(correctAns[0], wrongAns[0], max, max2);
}
if (lives == 0 && score == 0) { // Checks if user didnt get anything correct.
cout << "Wow.. 0 / 4. Thats not good." << endl;
}
else {
cout << "You got " << score << " Correct and had " << lives << " lives remaining" << endl;
}
cout << "\nThese are the questions you got wrong:\n";
}
string modifyQuestion(string q, int mod) {
for (int i = 0; i < q.length(); i++) {
if (i % mod == 0) { // If counter is divisible by the mod value.
q[i] = '*'; // Change current letter to an aterix.
}
}
return q; // return modified string back to the function.
}
string answersGiven(string correct[], string wrong[], int maxC, int maxW) {
for (int i = 0; i < maxC; i++) {
cout << correct[i] << " - Correct" << endl;
}
for (int i = 0; i < maxW; i++) {
cout << wrong[i] << " - Incorrect" << endl;
}
}
I've started programming using C++ few weeks back.
I'm working on an application store user input data into an array list. When entering user data the application must be able to check whether the user already exists in the array list.
The program is unable to store the user input or able to check whether the user already exists in the array list..
int linearSearch(int array[], int size, int searchValue)
{
for (int i = 0; i < size; i++)
{
if (searchValue == array[i])
{
return i;
break;
}
}
return -1;
}
void customerReg(){
const int Capacity = 99;
int cnic[Capacity];
int customerNic;
int search = 0;
cout << "Enter Customer NIC: \n";
cin >> cnic[Capacity];
search = linearSearch(cnic, Capacity, customerNic);
if (search != -1){
cout << "Customer is already registered!\n";
}
else {
string customerName;
cout << "Enter Customer Name: \n";
cin >> customerName;
}
What about:
...
cout << "Enter Customer NIC: \n";
cin >> customerNic; // <=== instead of: cnic[Capacity];
Other remarks:
the break is not necessary: the return will already interupt the search loop
cnic[Capacity] is out of range, so puting a value in it might cause some troubles
cnic[] is not initialised
It is not clear how you fill cnic[], which is by the way local to the function and be lost as soon as you return from it.
Depending how you initalize/fill cnic, it could make sense to keep track of the number of customers that are registered in the table.
Edit:
I assume that you can't use vectors or maps for your exercise, and that you're right at the beginning of your learning.
So I suppose that customerReg() is the first function that you are working on, and that others will follow (display, delete, modifiy...). If this is the case, you have to keep your customer data outside the functions:
const int Capacity = 99;
int cnic[Capacity] {};
int customer_count=0; // counter to the last customer inserted
Then in customerReg() you should call your search function using the number of customers instead of the maximal Capacity:
search = linearSearch(cnic, customer_count, customerNic);
Later, in the else branch you have to insert the new id into the array:
else {
if (customer_count==Capacity) {
cout << "Oops ! Reached max capacity"<<endl;
else {
string customerName;
cout << "Enter Customer Name: \n";
cin >> customerName;
...
cnic[customer_count] = customerNic; // here you store the id
... // store (I don't know where) the other customer elements you've asked for
customer_count++; // increment the number of users that are stored.
}
}
I have written a function in a program for entering a unique number but its not working. Something is wrong with the for loop.
I need to validate that employee id is unique.
I have made a structure named employee and "emp.id" is employee id. When the user inputs an id, it should not match previous Id's which user might have entered before. This is just a function of the main program, which validates that employee id is unique.
void uniquieid()
{
int check,i;
string code;
string tempemp1;
cout<< "enter id";
cin>> code;
while(!(num-1))
{
for(i=0;i<=num-1;i++)
{
if(emp[i].id.compare(code)==0)//comparing
{
check =1;
cout<<"enter id again";
break;
}
if(check=0) //csaasc
{
emp[i].id=code;
}
}
}
getch();
}
If the order that the ids are entered doesn't matter, I would do something like (note: untested):
using EmpIds = std::set<std::string>;
void addUniqueId(EmpIds& ids)
{
std::pair<EmpIds::iterator, bool> inserted;
const char* again = "";
do {
std::cout << "enter id" << again;
again = " again";
std::string id;
if (!(std::cin >> id))
throw std::runtime_error("No more ids!");
inserted = ids.insert(id);
} while (!inserted.second);
}
There are so many things wrong with the code, but maybe it should look more like this:
void uniqueid() {
int check=1;
string code;
string tempemp1;
cout<< "enter id";
while(check) {
cin >> code;
check = 0;
for (int i = 0; i < num; ++i) {
if (emp[i].id.compare(code)==0) {
check = 1;
cout << "enter id again";
break;
}
}
if (check==0) {
/* emp[i].id=code; */
}
}
getch();
}
Note how int check=1; starts at 1 to mean that the code needs re-entering.
So while(check) means that while the code is not unique keep going.
The for loop does the compare as before, but note the idiomatic form.
The other if (check==0) is outside the for loop and this means that no duplicates were detected so code can be used. However, I'm not sure which employee the code should apply to so I've just commented out the code.
Can you post the employee structure?
Because from this, everything looks OK, but your if function refers to emp.
So something in your structure is causing the problem.
Without your structure, anyone answering probably won't be able to find the problem.
Right now, all i can advise you to do is store employee ids in a vector and iterate through it using a for loop.
You could do
void uniqueid() {
std::vector<std::string> empIds;
std::string code;
CODE TO STORE IDs INTO VECTOR HERE;
int vectorLength = empIds.size();
std::cout << "enter id";
std::cin >> code;
for (int i = 0; i < vectorLength; i++) {
if (empIds[i] == code) {
std::cout << "enter id again";
std::cin >> code;
} else {
empIds.push_back(code);
}
}
}
For a start, something like the below should work.
map <string, bool> seen;
bool isUniqueId(string id)
{
return seen[id];
}
void addId(string id)
{
seen[id] = true;
}
From main(), whenever user inputs a string id, use isUniqueId(id) to ensure its unique, and if its unique, call addId(id).
Edit : (upon request from the OP)
Your transformed code may look like below after using map.
// Global map, defaults to false
map <string, bool> seen; // seen map to store if an id is seen already or not.
void uniqueId()
{
bool good = true; // set up a good flag to check if id is good or not.
int numEmployees = 0; // Count to store number of employees with unique ids so far
string id;
cout<< "enter id\n";
cin>> id;
while(good)
{
good = false; // Assume this is unique!
if(seen[id]) // Check if we already saw this id before
{
good = true; // Alas! We already have seen this id
cout<<"enter id again\n";
continue; // If id already exists, ask for another id setting good = true;
// Note that the above continue is NOT required as loop will run again (good = true).
// Just for clarity sake.
}
else
{
// Voila, we have a new employee with unique id.
seen[id] = true; // Unique, mark as seen now
emp[numEmployees].id=code; // Note numEmployees here
numEmployees++; // Increment the count
}
}
getch();
}
At the end of while loop, you would have successfully gotten a unique id from user, otherwise it will keep asking the user for new id.
I have a struct called users containing username information:
struct User{
string name;
string type;
int credit;
bool loginState;
};
My program reads in a txt file and creates an array of User struct types called "users" to store all the data. Im trying to create a function that deletes a user, so in the for loop below I'm searching for the string
userName
in the users array. If the user name exists then all the information of that user account is stored in the User temp. Otherwise an error is generated stating that the user entered does not exist.
string userName;
User temp;
cout<<"Please enter a username to delete:";
cin >> userName;
for(int i=0; i<usersSize; i++){
if((users[i].name).compare(userName) == 0){
temp.name = users[i].name;
temp.type = users[i].type;
temp.credit = users[i].credit;
temp.loginState = users[i].loginState;
}else{
cout << "Error: User does not exist";
}
}
I've tested my program and no matter what the input is, whether the user exists or not, the if statement always outputs the second condition. How can I fix this?
You need to first check if the user exists and then process the user which was found. The problem in your code is that the for loop checks all users and shows a message for all users but the one that matches (if any).
Check this code:
bool userWasFound = false;
int i;
for(i=0; i<usersSize; i++){
if((users[i].name).compare(userName) == 0){
userWasFound = true;
break;
}
}
// If no user was found, 'userWasFound' will still be 'false' at this point
if(userWasFound){
temp.name = users[i].name;
temp.type = users[i].type;
temp.credit = users[i].credit;
temp.loginState = users[i].loginState;
}else{
cout << "Error: User does not exist";
}
Use a flag to indicate that user found or not.. e.g;
bool flag=false;
for(int i=0; i<usersSize; i++){
if((users[i].name).compare(userName) == 0){
temp.name = users[i].name;
temp.type = users[i].type;
temp.credit = users[i].credit;
temp.loginState = users[i].loginState;
flag=true;
break;
}
}
if(!flag){
cout << "Error: User does not exist";
}
Hope it helped...
I have been trying to do this all day but something is just not OK. I'm trying to make a system that reads students from text file and creates three new files. The three files are: Normal, Failed, New. Everything depends of the student's number. If it has 'D' in the beginning the student should go to the file with failed students. If there is 'I' in front of the number the student should go to the file named "New". If there is nothing in the beginning the student should go to the "Normal" file.
The problem is that if the students data is inserted manually to the file by the user everything is ok. But I have a function that reads student's data and inserts it in the main file. If there is nothing in front of the number everything is ok when I try to read all students from the file. But if there is a letter, the data is not being written in the proper(any) file.
Here is example: Let's have a ready file with data in it:
989123 John Brown //Should go to the "Normal" file
I112233 Steve Round //Should go to the "New" file
D101010 Wayne Bruce //Should go to the "Failed" file
And if I try to read the data and insert it into the proper files everything is ok.
But let's say that the user has choosed the "Add student" option from the applications menu. And the user inserts a new record. For example:
D818181 Some Guy //Should go to the "Failed" file
but it doesn't go there. I don't know what's the reason. If the user has entered a student number without any letter everything is OK but if there is a letter it is not shown in the file. I hope you got my mind. Here is the code. Every help will be appreciated.
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
struct Student
{
int number;
string name;
string secondName;
};
Student Failed[50], New[50], Normal[50];
int o = -1;
int v = -1;
int n = -1;
int MakeInt(string number, bool ignoreFirst)
{
int num;
if(ignoreFirst)
{
number[0] = '0';
num = atoi(number.c_str());
}
else
{
num = atoi(number.c_str());
}
return num;
}
void zapis_student(string number, string name, string secondName)
{
if(number[0] == 'D')
{
int num = MakeInt(number, true);
Student temp;
temp.number = num;
temp.name= name;
temp.secondName = secondName;
o++;
Failed[o] = temp;
}
else if(number[0] == 'I')
{
int num = MakeInt(number, true);
Student temp;
temp.number = num;
temp.name = name;
temp.secondName = secondName;
v++;
New[v] = temp;
}
else
{
int num = MakeInt(number, false);
Student temp;
temp.number = num;
temp.name = name;
temp.secondName = secondName;
n++;
Normal[n] = temp;
}
}
void ReadFile()
{
ifstream fp("studenti.txt", ios::in);
if(fp.fail())
{
cout<<"Error!"<<endl;
}
while(fp.good())
{
string number, name, secondName;
fp >> number >> name >> secondName;
zapis_student(number, name, secondName);
}
fp.close();
}
void sortir(Student a[], int br)
{
for(int i = 0; i < br; i++)
{
for(int j = 0; j < br-1; j++)
{
if(a[j].number>a[j+1].number)
{
Student buf = a[j];
a[j] = a[j+1];
a[j+1] = buf;
}
}
}
}
void MakeFile(Student a[], int br, char ime_fail[])
{
ofstream fp(ime_fail);
for(int i = 0; i < br; i++)
{
fp << a[i].number << " " << a[i].name << " " << a[i].secondName << endl;
}
fp.close();
}
void AddStudent()
{
fstream fp("studenti.txt", ios::app);
string number, firstName, secondName;
cin >> number >> firstName >> secondName;
fp << number << " " << firstName << " " << secondName << endl;
fp.close();
}
void SortStudents()
{
sortir(Failed, o);
sortir(New, v);
sortir(Normal, n);
}
int main ()
{ int ans;
do
{ cout<<"******************************Menu***********************************"<<endl;
cout<<"* *"<<endl;
cout<<"* 1. Add student. *"<<endl;
cout<<"* 2. Read file. *"<<endl;
cout<<"* 3. Sort students. *"<<endl;
cout<<"* 4. Make Normal file. *"<<endl;
cout<<"* 5. Make Failed file. *"<<endl;
cout<<"* 6. Make New file. *"<<endl;
cout<<"* 7. Exit! *"<<endl;
cout<<"* *"<<endl;
cout<<"*********************************************************************"<<endl;
cout<<endl<<"Choice: "<<endl;
do
{cin>>ans;} while((ans<1)||(ans>7));
switch(ans)
{ case 1:AddStudent();break;
case 2:ReadFile();break;
case 3:SortStudents();break;
case 4:MakeFile(Normal, n, "Normal.txt");cout<<"Suzdaden e fail NovaGrupa.txt!\n";break;
case 5:MakeFile(Failed, o, "Failed.txt");cout<<"Suzdaden e fail Izklucheni.txt!\n";break;
case 6:MakeFile(New, v, "New.txt");cout<<"Suzdaden e fail Vlizashti.txt!\n";break;
case 7:exit(1);
}
}
while(ans!=7);
}
You have just one single student per type; since you start from -1, you finish the reading with 0, which is the right index for the first element but the wrong count of elements! To fix this, I simply suggest you to start with 0, use the index and then increment. E.g.
int o = 0;
...
Failed[o] = temp;
o++;
(swapped the lines), so that o keeps the count of how many student of that kind you've read so far.
Note: you also need to handle properly the end of file and cope with the case when there's nothing that can be converted to an integer by atoi: you try anyway (and you don't have a way to notice it), and the "normal" count can be one unit greater (after the fix; before the fix, it's the correct count!)
Other suggestions
Do not use atoi (for which you should include cstdlib, and you don't)… do not ignore compiler warnings
Last argument of MakeFile should be const char *
Use better names for variable: o, v, n are poorly named.