Error when passing vectors as parameter in Xcode - c++

I'm working on a program that I've seen other people do online except I'm trying to use functions to complete it to make it somewhat more challenging for me to help me better understand pointers and vectors. The problem I'm having in xcode is I keep getting this error..
Expected ';' after top level declarator
right here on my code,
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers) //<<< Error
{
cout << fixed << setprecision(2);
...
Where I am trying to use vector numbers in my function. Basically I want the numbers from the function passed back so that I can use them in another function I have not created yet. I've googled this error and it seems like no one can give a straight answer on how to fix this problem. Is anyone familiar with how to correct this? By no means is this code finished I'm just trying to get information regarding vectors as a parameter because from what I'm seeing syntax wise on other sites it looks to be correct. Thanks for your feedback.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <iterator>
using namespace std;
struct menuItemType{
string menuItem;
double menuPrice;
};
void getData(menuItemType (&mlist)[8]);
void showMenu(menuItemType (&menu_List)[8], vector<int> numbers);
int main() {
vector<int> temp;
menuItemType menuList[8];
getData(menuList);
showMenu(menuList,temp);
/*
cout << menuList[0].menuItem << " " << menuList[0].menuPrice << endl;
cout << menuList[1].menuItem << " " << menuList[1].menuPrice << endl;
*/
return 0;
}
void getData(menuItemType (&mlist)[8]){
string Str;
ifstream infile;
infile.open("cafe135.txt");
if(infile.is_open())
{
for (int i = 0; i < 8; ++i){
infile >> mlist[i].menuItem >> mlist[i].menuPrice;
}
}
else cout << "Unable to open file";
}
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers)
{
cout << fixed << setprecision(2);
string choice;
cout << "Would you like to view the menu? [Y] or [N]: ";
cin >> choice;
cout << endl;
int x = 3;
int count = 1;
while (choice != "Y" && choice != "N" && choice != "y" && choice != "n")
{
if (count == 4){
return;
}
cout << "Error! Please try again ["
<< x
<< "] selections remaining: ";
cin >> choice;
cout << endl;
x--;
count++;
}
if (choice == "N" || choice == "n"){
return;
}
else
{
cout << "___________ Breakfast Menu ___________" << endl;
for (int i = 0; i < sizeof(menu_List)/sizeof(menu_List[0]); ++i)
{
cout << "Item "
<< (i+1)
<< ": "
<< menu_List[i].menuItem
<< " "
<< menu_List[i].menuPrice
<< endl;
}
cout << endl;
string itemSelection = " ";
//int str_length = 0;
cout << "Select your item numbers separated"
<< " by spaces (e.g. 1 3 5) Select 0 to cancel order: ";
cin.ignore();
getline(cin, itemSelection);
if (itemSelection == "0")
{
return;
}
vector<int> vectorItemSelection;
stringstream text_stream(itemSelection);
string item;
while (getline(text_stream, item, ' '))
{
vectorItemSelection.push_back(stoi(item));
}
int n = vectorItemSelection.size();
int arr[n];
for (int i = 0; i < n; i++)
{
arr[i] = vectorItemSelection[i];
}
}
}

Compare how menu_List is declared in this line
void showMenu(menuItemType (&menu_List)[8], vector<int> numbers);
and this line
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers)
The first one is correct.
But I have to agree with the comments above, you are mixing up a lot of different things here. Just use vectors, 99% of the time it's the right thing to do anyway. and it's easier to learn one thing at a time.
Prefer to write your code like this
void getData(vector<menuItemType>&);
void showMenu(vector<menuItemType>&, vector<int> numbers);
int main() {
vector<int> temp;
vector<menuItemType> menuList(8);
...
See? Just use vectors everywhere.

Related

How to connect sections of an array or organize an array the same as another?

I am not sure how to connect a part of an array or if it is even possible.
My code is as follows:
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
string name;
string date[3];
double height[3];
double enter;
cout << "Enter name of a pole vaulter: ";
cin >> name;
cout << "Enter date of first vault: ";
cin >> date[0];
cout << "Enter height of first vault: ";
cin >> enter;
if (enter >= 2.0)
{
if (enter <= 5.0)
{
height[0] = enter;
}
else
{
cout << "Incorrect Value";
abort();
}
}
else
{
cout << "Incorrect Value";
abort();
}
cout << "Enter date of second vault: ";
cin >> date[1];
cout << "Enter height of second vault: ";
cin >> enter;
if (enter >= 2.0)
{
if (enter <= 5.0)
{
height[1] = enter;
}
else
{
cout << "Incorrect Value";
abort();
}
}
else
{
cout << "Incorrect Value";
abort();
}
cout << "Enter date of third vault: ";
cin >> date[2];
cout << "Enter height of third vault: ";
cin >> enter;
if (enter >= 2.0)
{
if (enter <= 5.0)
{
height[2] = enter;
}
else
{
cout << "Incorrect Value";
abort();
}
}
else
{
cout << "Incorrect Value";
abort();
}
int len = sizeof(height) / sizeof(height[0]);
sort(height, height + len, greater<int>());
cout << "Stats for " << name << ":" << endl;
for (int i = 0; i < len; i++) {
cout << height[i] << " ";
}
cout << height[0];
}
I am trying to enter dates and a double value, and then organize the double values in descending order and keep the dates with the corresponding value. I am not sure if this is possible, any alternative way of completing this would be helpful.
Thank you
Group of data, data sorting, multiple data points that should be aligned/connected to their respective other data points. I think the best solution here would be the use of a struct or class with vectors:
Let's say you want a variable that contains both your date and number. We can construct a class or structure for that:
#include <iostream>
using namespace std;
struct str1
{
string date;
double number;
};
class cls1
{
public:
string date;
double number;
};
int main()
{
str1 ob1;
cls1 ob2;
ob1.date = "somedate";
ob1.number = 12345;
cin >> ob1.date;
cout << ob1.date << " " << ob1.number << endl;
ob2.date = "somedate2";
ob2.number = 54321;
cin >> ob2.number;
cout << ob2.date << " " << ob2.number << endl;
return 0;
}
Having a class or struct enables you to use objects (variables made from those structs or classes). Every object created has their own place in memory for storing both date and number. You can use, find, search any of these variables and have access to both values this way.
Grouping them up so there's a list of them can be done in vectors.
Vectors are like better arrays. They not only have a dynamical size (meaning its size can change and doesnt stay static like in arrays), but they also have quite a bit ready made functions for you to use:
bool sortingFunction(int &a, int &b)
{
if (a > b) return true;
else return false;
}
int main2()
{
vector<int> numbers;
//to add
numbers.emplace_back(5); //5 is the number to add
//to remove
numbers.erase(numbers.begin() + 2); //2 is the index of the variable to delete
//to sort
sort(numbers.begin(), numbers.end(), sortingFunction);
return 0;
}
Vectors need the #include <vector> header.
Sort is a function that sorts. Needs #include <algorithm> header.
Sort function is neat because you can define the logic behind how you want to sort the vector or array with a seperate function that returns either true or false.
For your example you could do something like this in the end:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct myType
{
string date;
double number;
};
bool sortByDate(myType &a, myType &b)
{
if (a.date > b.date) return true;
else return false;
}
bool sortByNumber(myType &a, myType &b)
{
if (a.number > b.number) return true;
else return false;
}
int main()
{
vector<myType> variables;
int num;
cout << "how many do you want to add" << endl;
cin >> num;
for(int i = 0; i < num; i++)
{
myType tmp;
cout << "Enter date of var" << i+1 << ": ";
cin >> tmp.date;
cout << "Enter number of var" << i+1 << ": ";
cin >> tmp.number;
variables.emplace_back(tmp);
}
//after that you can use the vector as you want...
//sort
sort(variables.begin(), variables.end(), sortByDate);
sort(variables.begin(), variables.end(), sortByNumber);
//delete
variables.erase(variables.begin()+5);
//or clear the entire thing
variables.clear();
//Either way each item in the vector consists of both number and date thus even
//if you sort the vector the values are still connected at the same position
return 0;
}

How to Accept [ENTER] key as an invalid input and send out error message

This is a program that grade user inputs for the questions of Driver's License Exam.
I'm having trouble of validating the user input.
I'd like to accept the [ENTER] key as an invalid input and proceed to my validation rather than just go to an empty line and cannot process to the next question. Purpose is to send out error message and that no input is given and [ENTER] key is not valid input and only accept one more chance to enter valid input which are a/A, b/B, c/C, or d/D. So that is why I'm using if statement here instead of loop.
I tried if (testTakerAnswers[ans] == (or =) '\n') {} but still doesn't solve the problem of newline.
I include curses.h in here hope to use getch() statement from the other post but somehow I can't manage to work in my code with an array instead of regular input.
I'm looking for other methods as well rather than getch()
So should I adjust my bool function, or directly validate input in main() function.
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
#include <curses.h>
using namespace std;
const unsigned SIZE = 20; // Number of qns in the test
char testTakerAnswers[SIZE]; //Array to hold test taker's answers
bool validateInput(char);
class TestGrader
{
private:
char answers[SIZE]; // Holds the correct answers // Answer is array
int getNumWrong (char[]);
void missedQuestions (char[]);
public:
void setKey(string); // Initialize object with standard keys
void grade(char[]); // Grades the answers from tester
};
void TestGrader::setKey(string key){
if (key.length()!=SIZE){
cout << "Error in key data.\n";
return;
}
for (unsigned pos = 0; pos < SIZE ; pos ++)
answers [pos] = key [pos];
}
void TestGrader::grade(char test[])
{
int numWrong = getNumWrong(test);
if (numWrong <= 5)
cout << "Congratulations. You passed the exam.\n";
else
cout << "You did not pass the exam. \n";
cout << "You got " << (SIZE-numWrong) << " questions correct. \n";
if (numWrong > 0){
cout << "You missed the following " << numWrong << " questions: \n";
missedQuestions(test);
}
}
int TestGrader::getNumWrong(char test[])
{
int counter = 0;
for (int i = 0; i < SIZE; i++){
if (answers[i] != toupper(testTakerAnswers[i])){
counter++;
}
}
return counter;
}
void TestGrader::missedQuestions(char test[])
{
// cout << testTakerAnswers[i]; This is to print taker's answers
int counter = 0;
for (int i = 0; i < SIZE; i++){
if (answers[i] != toupper(testTakerAnswers[i])){
cout << "\n" << i + 1 << ". Correct answers: " << answers[i];
counter++;
}
}
}
bool validateInput(char ans){ // Only A, B, C, D valid input
if (toupper(ans)!='A' && toupper(ans)!= 'B' && toupper(ans)!='C' && toupper(ans)!= 'D'){
cout << "\n********************WARNING*******************\n";
cout << "Invalid input! Enter only a/A, b/B, c/C, or d/D\n";
return false;
}
if (testTakerAnswers[ans] == '\n'){
return false;
}
return true;
}
int main()
{
const int NUM_QUESTIONS = 20;
string name; //Test taker's name
char doAnother; //Control variable for main processing loop
TestGrader DMVexam; //Create a TestGrader object
DMVexam.setKey("BDAACABACDBCDADCCBDA");
do {
cout << "Applicant Name: ";
getline(cin,name);
cout << "Enter answer for " << name << ".\n";
cout << "Use only letters a/A, b/B, c/C, and d/D. \n\n";
for (int i = 0; i < NUM_QUESTIONS; i++){
// Input and validate it
do{
cout << "Q" << i+1 << ": ";
cin >> testTakerAnswers[i];
if (!validateInput(testTakerAnswers[i])){
cout << "You get one more chance to correct.\nOtherwise, it count as wrong answer.";
cout << "\n*********************************************";
cout << "\nRe-enter: ";
cin >> testTakerAnswers[i];
cout << '\n';
break;
}
}while(!validateInput(testTakerAnswers[i]));
}
//Call class function to grade the exam
cout << "Results for " << name << '\n';
DMVexam.grade(testTakerAnswers);
cout << "\nGrade another exam (Y/N)? ";
cin >> doAnother;
while (doAnother != 'Y' && doAnother != 'N' && doAnother != 'y' && doAnother != 'n'){
cout << doAnother << " is not a valid option. Try Again y/Y or n/N" << endl;
cin >> doAnother;}
cout << endl;
cin.ignore();
}while(doAnother != 'N' && doAnother != 'n');
return 0;
}
Your issue is cin >> testTakerAnswers[i]; cin is whitespace delimited, that means that any whitespace (including '\n') will be discarded. So testTakerAnswers[i] can never be '\n'.
I'm not sure exactly what you want to do, but possibly try
getline(cin,input_string);
then
input_string == "A" | input_string == "B" | ...
So if only the enter key is pressed, input_string will become "".

What is a deleted function, and why only my functions that I pass files into are considered deleted? [duplicate]

This question already has answers here:
Using fstream Object as a Function Parameter
(3 answers)
Closed 6 years ago.
#include <bits/stdc++.h>
using namespace std;
class contact {
private:
vector< pair<string, int> > contact_info;
public:
void add_contact(string contact_name, int contact_number) {
contact_info.push_back(make_pair(contact_name, contact_number));
sort(contact_info.begin(),contact_info.end());
}
void edit_contact(string contact_name) {
int found_at;
for (unsigned int i =0; i < contact_info.size(); i++) {
if (contact_info[i].first == contact_name) {
found_at = i;
}
}
if (contact_info[found_at +1].first == contact_name) {
int choice;
int counter = found_at;
int index = 1;
while (contact_info[counter].first == contact_name) {
cout << index << ". " << contact_info[counter].first << " " << contact_info[counter].second;
counter++;
index++;
}
cout << "Choose any please: ";
cin >> choice;
found_at = found_at - (choice - 1);
}
cout << "Enter the new number: ";
cin >> contact_info[found_at].second;
}
void show_all() {
for (unsigned int i =0; i < contact_info.size(); i++) {
cout << contact_info[i].first << " " << contact_info[i].second << endl;
}
}
void delete_contact(string contact_name) {
int found_at;
for (unsigned int i =0; i < contact_info.size(); i++) {
if (contact_info[i].first == contact_name) {
found_at = i;
}
}
if (contact_info[found_at +1].first == contact_name) {
int choice;
int counter = found_at;
int index = 1;
while (contact_info[counter].first == contact_name) {
cout << index << ". " << contact_info[counter].first << " " << contact_info[counter].second;
counter++;
index++;
}
cout << "Choose any please: ";
cin >> choice;
found_at = found_at - (choice - 1);
}
contact_info.erase(contact_info.begin()+found_at);
}
void writeFile(ofstream contact_file) {
for (unsigned int i =0; i < contact_info.size(); i++) {
contact_file << contact_info[i].first << " " << contact_info[i].second << endl;
}
}
void readFile(ifstream contact_file) {
string input;
while (!contact_file.eof()) {
contact_file >> input;
size_t pos = input.find(" ");
string name = input.substr(0,pos);
string number_str = input.substr(pos);
int number = stoi(number_str) ;
contact_info.push_back(make_pair(name,number));
}
}
};
int main()
{
int choice;
ifstream contacts_file_read;
contacts_file_read.open("contacts.txt");
ofstream contacts_file_write;
contacts_file_write.open("contacts.txt");
bool in_prog = true;
contact contacts;
string name;
int number;
while (in_prog) {
cout << "1. Add contacts" << endl
<< "2. Edit contact" << endl
<< "3. Delete contact" << endl
<< "4. Show all" << endl
<< "5. exit" << endl;
cout << "Your choice: ";
cin >> choice;
contacts.readFile(contacts_file_read);
if (choice == 1) {
cout << "Enter name & number separated by a space: ";
cin >> name >> number;
contacts.add_contact(name, number);
} else if (choice == 2) {
cout << "Enter name of contacts to be edited: ";
cin >> name;
contacts.edit_contact(name);
} else if (choice == 3) {
cout << "Enter name of contact to be deleted: ";
cin >> name;
contacts.delete_contact(name);
} else if (choice == 4) {
contacts.show_all();
} else if(choice == 5) {
contacts.writeFile(contacts_file_write);
} else {
cout << "Wrong choice" << endl;
}
}
return 0;
}
So, I was asked in my programming class to make a phone book application in C++ using only objects, so this is my attempt at it.
All functions are good, I did recompile the program after finishing each function at it gave me 0 errors, however whenever I try to call writeFile or readFile function that were previously working fine, now the compiler gave me an error of "error: use of deleted functions... "
I don't know what are deleted functions and why only functions that take file objects as an argument are treated as such.
Can anyone please help?
Thanks.
Objects of type std::ifstream are not copyable -- indeed, the object represents the unique handle of an open file, and it would be difficult to conceptualize what it would mean to copy such unique responsibility.
Indeed, this inability to copy an object is encoded by making the copy constructor deleted, which causes the error that you see when you do attempt to copy it.
Your code should pass the original ifstream, not a copy (by taking a reference parameter):
void readFile(ifstream & contact_file)
// ^^^^^^^^^^

Vector of strings comparison C++

I am writing a code about input strings, then compare them with other elements in the vector and, if there's a positive match, don't put them into. I wrote this:
// NamePair.cpp : definisce il punto di ingresso dell'applicazione console.
//
#include "stdafx.h"
#include "std_lib_facilities.h"
#include <vector>
int _tmain(int argc, _TCHAR* argv[])
{
vector<string> names;
vector<int> scores;
string name = "0";
int score = 0;
int error = 0;
int n = 0;
cout << "Type a name and a score: " << endl;
while (cin >> name >> score) {
++n;
cout << "This is # " << n << " name you typed." << endl;
if (n >= 2) {
for (int i : scores) {
if (names[i] == name) {
cout << "You have already typed this name dude!" << endl;
}
else if (name != "NoName") {
names.push_back(name);
scores.push_back(score);
}
else {
break;
}
}
}
}
for (int i = 0; i < scores.size(); ++i) {
cout << names[i] << "\t" << scores[i] << endl;
}
keep_window_open();
return 0;
}
The issue is that when I am trying to run the program it works but it seems to be stuck at a point where I continuously add names and scores but it doesn't do anything apparently (neither shows a warning message nor stops if "NoName" string is typed). I can't figure out why! I have tried to re-write it all but with the same result...
Thanks for help!
Your checking whether name exists in vector is wrong. Change
if (names[i] == name) {
to
if ((std::find(names.begin(), names.end(), name) != names.end()) {
Also, it looks like the for (int i : scores) loop is unnecessary here.
An std::map would be best suitable here. This code snippet will help you
#include <bits/stdc++.h>
using namespace std;
int main() {
map<string, int> data;
string name;
int score;
for (int n = 0; cin >> name >> score; ++n) {
if (name != "NoName" || !data.count(name))
data[name] = score;
}
for (auto & i : data)
cout << i.first << " " << i.second << endl;
return 0;
}
See http://ideone.com/j3Gkiw
Your issue is in your for loop.
You try to push new elements into your vector inside the loop that iterates the vector. The vector starts out empty, so the program will never enter the loop and you will never actually push any elements into the vectors.

How to use a dynamically sized array of structs?

I have to make my homework. It is console application which uses an array of structs that keep information about a computer(brand, year of manufactoring, weight and inventory number). So I wrote a completely working program, but I want to use a dynamic array, because I dont know how many records the user will input.
Is there way to do this. To add new records in array until the user say n/N? Any suggestions?
This is my version of program:
#include "stdafx.h"
#include <iostream>
using namespace std;
struct ComputerInfo
{
char computerMark[20], invertarNumber[6];
unsigned int year;
float weight;
};
ComputerInfo computerArray[300];
ComputerInfo AddComputers(ComputerInfo compterArray[], int counter)
{
cout << "Enter mark of the computer: ";
cin >> computerArray[counter].computerMark;
cout << "Enter year of establish: ";
cin>> computerArray[counter].year;
while ((computerArray[counter].year < 1973)
|| (computerArray[counter].year > 2013))
{
cout << "INVALID YEAR!!!" << endl;
cout << "Enter year of establish: ";
cin>> computerArray[counter].year;
}
cout << "Enter computer weidth: ";
cin >> computerArray[counter].weight;
cout << "Enter computer invertar number(up to six digits): ";
cin >> computerArray[counter].invertarNumber;
return computerArray[counter];
}
void ShowRecords()
{
int counter = 0;
while (computerArray[counter].year != 0)
{
cout << "Mark: " << computerArray[counter].computerMark << endl;
cout << "Year: " << computerArray[counter].year << endl;
cout << "Weidth: " << computerArray[counter].weight << endl;
cout << "Inv. number: " << computerArray[counter].invertarNumber << endl << endl;
counter++;
}
}
void MoreThanTenYearsOld(ComputerInfo computerArray[])
{
int counter = 0;
float counterOldComputers = 0;
float computerPer = 0;
while (computerArray[counter].year == 0)
{
if (computerArray[counter].year <= 2003)
{
counterOldComputers++;
}
counter++;
}
computerPer = counterOldComputers / 3;
cout << endl;
cout << "Percantage of old computers is: " << computerPer << endl;
}
int main()
{
int counter = 0;
float computerPer = 0;
char answer = 'y';
for (int i = 0; i <= 299; i++)
{
strcpy(computerArray[i].computerMark,"");
}
while((answer == 'Y') || (answer == 'y'))
{
computerArray[counter] = AddComputers(computerArray, counter);
cout << endl;
cout << "Do you want to enter more records (Y/N): ";
cin >> answer;
cout << endl;
counter++;
}
MoreThanTenYearsOld(computerArray);
return 0;
}
Yes. Instead of your array, use
std::vector<ComputerInfo> computerArray;
and you can add as many objects as you want:
ComputerInfo c;
// read the data
computerArray.push_back(c);
now, computerArray[0] will have the info in c.
You'll need to #include <vector>.
Also, instead of char computerMark[20] you can use a std::string.
You have two options:
1) Use std::vector instead of an array. This is a very powerful tool and certainly worth learning how to use.
2) Dynamically allocate the array and resize it as you add more items. Basically this means writing your own version of std::vector. This is a good way to strengthen your programming skills. You will learn what goes into writing standard classes and functions. However, I advise using std::vector in more serious programming because it has already been thoroughly tested and debugged.