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.
so i have this set of strings which are stored in an array i want to search the array so when the string is found it should say found and when its not found it should say invalid
this is what i have so far
cout << "Enter a Name to Search" <<endl;
cin >>userInput;
for (int i=0; i<size; i++)
{
if (first_name[i]==userInput)
{
cout <<"Found"<<endl;
}else{
cout << "InValid"<<endl;
break;
}
}
so every time i run this i am always redirected to The else Statement is there anyway for me to fix this
Use containers like std::set and std::unordered_set for fast searching.
#include <iostream>
#include <unordered_set>
#include <string>
int main()
{
std::unordered_set<std::string> first_name;
first_name.insert("Joe");
first_name.insert("Anderson");
//....
std::string input;
std::cin >> input;
std::unordered_set<std::string>::iterator searchResult = first_name.find(input); // Search for the string. If nothing is found end iterator will be returned
if(searchResult != first_name.end())
std::cout << "Found!" << std::endl;
else
std::cout << "Not found!" << std::endl;
}
Programm output when "Joe" was typed:
Found!
Press <RETURN> to close this window...
For your example everything is okey, if userInput is std::string, first_name is array of std::string and variable size store array size.
You are breaking from the else part. So for instance if the array is size of 10, and if you give userinput as string present in 5th array element, your code will break at the first iteration of the for loop. Try the below code. If match found, It will print "found", or if the the userinput not there in the array it will print invalid. Hope it helps. Initialize the "first_name" with your array element and change the size.
string userInput;
string first_name[10];
int i=0;
int size = 10;
first_name[0] = "Hi";
first_name[1] = "Hii";
first_name[2] = "Hiii";
cout << "Enter a Name to Search" <<endl;
cin >> userInput;
for (i = 0; i<size; i++)
{
if (first_name[i] == userInput)
{
cout <<"Found"<< endl;
break;
}
}
if(i == size)
cout << "Invalid" << endl;
I think a more elegant solution would use a boolean flag, like:
cout << "Enter a Name to Search" <<endl;
cin >>userInput;
bool found = false;
for (int i=0; i<size; i++)
{
if (first_name[i]==userInput)
{
found = true;
break;
}
}
cout << (found?"found":"invalid") << endl;
so i was able to find a solution this is what i did
string result =""; //set a string named result
cout << "Enter a Name to Search" <<endl;
cin >>userInput;
for (int i=0; i<size; i++)
{
if (!(first_name[i]==userInput))
{
result = "Found";
break;
}else{
result ="InValid";
}
}
cout <<result<<endl; //outside of for loop
I've come across a little problem, how do I print the winning candidate's name? See the instructions here are, input five names, their number of votes and percentage of votes, whoever has the highest wins. I don't know if I did my code right, but it works.. well except for the name part. I've tried everything from a lot of for loops to transfer the array or what.
I'm almost done with the code.
Here's the code
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
char candidates[50];
int votes[5]={0};
float percent[5]={0};
int a,b,c,d,e,i;
int maxx;
int champ=0;
char winner[50];
cout << "Enter the candidates' last names: ";
cout << endl;
for(a=1;a<=5;a++)
{
cout << a << ". ";
cin >> candidates;
}
cout << endl;
cout << "Enter their number of votes: " << endl;
for(b=1;b<=5;b++)
{
cout << b << ". ";
cin >> votes[b];
}
cout << endl;
cout << "percentage of votes: " << endl;
for(c=1;c<=5;c++)
{
cout << c << ". ";
percent[c]=votes[c]*0.2;
printf("%.2f\n", percent[c]);
}
cout <<"Candidates\t\tVotes\t\t% of Votes" << endl;
for(int k=1;k<=5;k++)
{
cout << candidates[k] << "\t\t\t" << votes[k] << "\t\t\t";
printf("%.2f\n", percent[k]);
}
maxx=percent[0];
for(d=1;d<=5;d++)
{
if(maxx<percent[d]);
{
//what happens here?
}
}
return 0;
}
You should keep a 2d array of characters or array of string for storing candidate names instead of a 1-d array.
char candidates[5][10]; //
for(int i = 0; i < 5; i++)
{
cin >> candidates[i];
}
Then keep a variable to store index for winning candidate
int winIndex = 0;
int winPercent = 0;
for(int i = 0; i < 5; i++)
{
if(percent[i] > winPercent)
{
winPercent = percent;
winIndex = i;
}
}
Finally print name of winning candidate;
cout << candidates[winIndex];
In object oriented approach, you may create a class with following information
class Candidate
{
string name;
int votes;
float percent;
};
Use string candidates[50]; instead of char candidates[50];
then cin >> candidates[a];
I've been assigned by school to create an application that contains a book list with 20 different books in it and build a menu with following options:
(a) List – Display the list in tabular format. Each display should contain an appropriate heading and column captions;
(b) Search – Search for a book record in the list using the ISBN and print the full record for the book;
(c) Delete – Delete an existing book record from the list;
(d) Exit – Stop the program.
Here is the sample of my program:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <cctype>
using namespace std;
typedef struct
{
char code[50];
char author[50];
char name[50];
char edition[50];
char publish[50];
char price[50];
} BOOK_LIST;
void list (BOOK_LIST book[], int rows);
void showBook (BOOK_LIST book[], int rows);
void updateRecord (BOOK_LIST book[], int rows);
void advancedSearch (BOOK_LIST book[], int rows);
int deleteBook (BOOK_LIST book[], int rows);
int searchBook(BOOK_LIST book[], int rows);
int main()
{
ifstream inFile("list.txt");
if(!inFile)
cout << "Error opening input file\n";
else
{
BOOK_LIST books[50];
int index = -1, choice;
inFile.getline(books[++index].code, 50);
while(inFile)
{
if(inFile.peek() == '\n')
inFile.ignore(256, '\n');
inFile.getline(books[index].author, 50);
inFile.getline(books[index].name, 50);
inFile.getline(books[index].edition, 50);
inFile.getline(books[index].publish, 50);
inFile >> books[index].price;
// read next number
inFile >> books[++index].code;
}
inFile.close();
// menu starts
do
{
cout << "Do you want to:\n";
cout << "1. List all books\n";
cout << "2. Get details about a book\n";
cout << "3. Delete a book from the list\n";
cout << "4. Exit\n";
cout << "5. Advanced Search\n";
cout << "Enter choice: ";
cin >> choice;
switch (choice)
{
case 1 : list(books, index);
break;
case 2 : showBook(books, index);
break;
case 3 : updateRecord(books, index);
break;
case 5 : advancedSearch(books, index);
case 4 : break;
default: cout << "Invalid choice\n";
}
} while (choice != 4);
ofstream outFile("list.txt");
if(!outFile)
cout << "Error opening output file, records are not updated.\n";
else
{
for (int i = 0; i < index; i++)
{
outFile << books[i].code << endl;
outFile << books[i].author << endl;
outFile << books[i].name << endl;
outFile << books[i].edition << endl;
outFile << books[i].publish << endl;
outFile << books[i].price << endl;
}
outFile.close();
}
}
return 0;
}
void list(BOOK_LIST book[], int rows)
{
cout << fixed << setprecision(2);
cout << "ISBN\t Author BookName Edition\tPublisher\t Price\n";
for (int i = 0; i < rows; i++)
cout << book[i].code << "\t" << book[i].author << "\t"
<< book[i].name << "\t" << book[i].edition << "\t"
<< book[i].publish << "\t"
<< " " << book[i].price << endl;
return;
}
int searchBook(BOOK_LIST book[], int rows)
{
int i = 0;
bool found = false;
char code[50];
cout << "Enter an ISBN code of a book to search: ";
fflush(stdin);
cin.getline(code, 50);
while (i < rows && !found)
{
if (strcmp(code, book[i].code) == 0)
found = true;
else
i++;
}
if (found)
return i;
else
return -1;
}
void showBook(BOOK_LIST book[], int rows)
{
int pos = searchBook(book, rows);
if (pos != -1)
{
cout << "Author is " << book[pos].author << endl;
cout << "Book name is "<< book[pos].name << endl;
cout << book[pos].edition << " Edition" << endl;
cout << "The publisher of this book is " << book[pos].publish << endl;
cout << "Current price is " << book[pos].price << endl;
}
else
cout << "Product not found\n";
return;
}
void updateRecord(BOOK_LIST book[], int rows)
{
int pos = deleteBook(book, rows);
char code [50];
int i,j = 0;
for(i = 0; i < rows ; i++)
{
if(strcmp(code, book[i].code))
{
strcpy(book[j].code , book[i].code);
strcpy(book[j].author, book[i].author);
strcpy(book[j].name, book[i].name);
strcpy(book[j].edition, book[i].edition);
strcpy(book[j].publish, book[i].publish);
strcpy(book[j].price, book[i].price);
j++;
}//if
else
{
i++;
strcpy(book[j].code, book[i].code);
strcpy(book[j].author, book[i].author);
strcpy(book[j].name, book[i].name);
strcpy(book[j].edition, book[i].edition);
strcpy(book[j].publish, book[i].publish);
strcpy(book[j].price, book[i].price);
j++;
}//else
}//for
return;
}
int deleteBook (BOOK_LIST book[], int rows)
{
int i = 0;
bool found = false;
char code[50];
cout << "Enter an ISBN code of a book to delete: ";
fflush(stdin);
cin.getline(code, 50);
while (i < rows && !found)
{
if (strcmp(code, book[i].code) == 0)
found = true;
else
i++;
}
if (found)
return i;
else
return -1;
}
void advancedSearch (BOOK_LIST book[], int rows)
{
char advanced[50];
cout << "Please enter either the author's name or the book name to search: ";
fflush(stdin);
cin.getline(advanced, 50);
for(int i = 0; i < rows; i++)
{
if(strstr(book[i].author, advanced) || strstr(book[i].name, advanced))
{
cout << "ISBN is " << book[i].code << endl;
cout << "Author is " << book[i].author << endl;
cout << "Book name is " << book[i].name << endl;
cout << book[i].edition << " Edition" << endl;
cout << "Publisher is " << book[i].publish << endl;
cout << "Current price is " << book[i].price << endl;
}
}
return ;
}
The problem starts here:
When I want to permanently delete a whole row of book record. But the book record is still there after deleting.
First, this is my menu, then I press 1 to check the list for the IBSN. Then, I press 3 to proceed to the deleting part. At that time, I choose TheHost to delete. After the deleting, to ensure that I have deleted the chosen book, so I press 1 to check the list again, but unfortunately the book is still there:
If I am able to delete a book record, and how do I delete a record permanently? And after deleting a record, how do I move the remaining records upwards, so that it won't leave any empty row there?
The function for the deleting:
void updateRecord(BOOK_LIST book[], int rows)
{
int pos = deleteBook(book, rows);
char code [50];
int i,j = 0;
for(i = 0; i < rows ; i++)
{
if(strcmp(code, book[i].code))
{
strcpy(book[j].code , book[i].code);
strcpy(book[j].author, book[i].author);
strcpy(book[j].name, book[i].name);
strcpy(book[j].edition, book[i].edition);
strcpy(book[j].publish, book[i].publish);
strcpy(book[j].price, book[i].price);
j++;
}//if
else
{
i++;
strcpy(book[j].code, book[i].code);
strcpy(book[j].author, book[i].author);
strcpy(book[j].name, book[i].name);
strcpy(book[j].edition, book[i].edition);
strcpy(book[j].publish, book[i].publish);
strcpy(book[j].price, book[i].price);
j++;
}//else
}//for
return;
}
The Text file that I used in this program a.k.a the BOOK_LIST
I see (at least) two problems with your code around deleting a book.
in update_record you're using a char code[50] which is being used to compare with strcmp later on but is not initialized.
when you delete a book you should update your index which becomes rows in the update_record method. However index is passed to rows by value which means that even if you try running --rows; in update_record it won't decrement index. You'll need to pass it by reference for it to update index.
On a side note, I agree with comments regarding fixing your code to use vectors/maps & strings instead of simple arrays and char*.
But since you mentioned it was a school task I would guess you haven't reached that sort of material yet.
Good Luck.
The assignment most probably expects you to use std::list template rather than the classical C array. Insertion and deletion is natural for lists.
An alternative would be to use std:map using the ISBN as a key. ISBN is supposed to be globally unique.
Just to expand on my comment, here is one way to remove an element from an array.
Suppose we have an array of char called X, containing {'a', 'b', 'c', 'd', 'e', 'f'}, and we want to get rid of 'c'.
If we want to maintain the order of the remaining elements, then what we're aiming for is {'a', 'b', 'd', 'e', 'f'}. So we copy the 'd' into the 'c' place, the 'e' into the old 'd' place, and so on:
a b c d e f
a b d d e f
a b d e e f
a b d e f f
We can do this with code like
for(int k=2; k<5; ++k)
X[k] = X[k+1];
And what happens to that extra 'f' at the end? We could write some placeholder into that unwanted space, and then watch out for that placeholder for the rest of the run. Or, we could just stop using that space, and say that from now on we're considering an array of length 5. That extra 'f' will still be there, but for now we don't care about what exists past the end of our array.
(If we don't care about the order of the remaining elements, then we can make this a lot simpler.)
Remember, it's always easier to develop new functionality in isolation.
Once you have this working, you can apply it in your code and get a passing grade, but if you really want to learn something useful you should write a Book class.
This program is pretty self explanatory, so I won't really get into the purpose of what its for.
My main problem right now is on lines 82, 89, 95, and 101, I'm getting "Undeclared Identifier" errors for "arr" and "input" when i compile.
Is this because I declared them inside of an if else if construct, and if so, is there any way to get around this. Thanks for any help in advance!!!!
Here is the code
#include <iostream>
#include <string>
using namespace std;
template<class T> void selectionSort(T arr[], T num)
{
int pos_min;
T temp;
for (int i = 0; i < num - 1; i++)
{
pos_min = i;
for (int j = i + 1; j < num; j++)
{
for (arr[j] < arr[pos_min])
{
pos_min = j;
}
}
if (pos_min != i)
{
temp = arr[i];
arr[i] = arr[pos_min];
arr[pos_min] = temp;
}
}
}
int main()
{
char check = 'C';
while (toupper(check) != 'Q')
{
char dataType;
int num = 0;
cout << "What kind of data do you want to sort?" << endl;
cout << " For integer enter i, for string enter s, for character enter c. ";
cin >> dataType;
//User input dataType
if (toupper(dataType) == 'I')
{
int arr[100];
int input;
cout << " You've chosen Integer dataType" << endl;
}
else if (toupper(dataType) == 'S')
{
string arr[100];
string input;
cout << " You've chosen String dataType" << endl;
}
else if(toupper(dataType) == 'C')
{
char arr[100];
char input;
cout << " You've chosen Character dataType" << endl;
}
else
{
cout << "Not a recognizable dataType. Shuting down..." << endl;
return -1;
}
//User input # of num
cout << "How many num will be sorted? ";
cin >> num;
for (int i = 0; i < num; i++)
{
cout << "Enter an input of the dataType you selected: ";
cin >> input;
arr[i] = input;
}
//Display user input
cout << "The data as you entered it: ";
for (int i = 0; i < num; i++)
{
cout << arr[i];
cout << " ";
}
cout << endl;
//Sort user input by calling template functon selectionSort
selectionSort(arr, num);
//Display sorted user input
cout << "After sorting your data by calling selectionSort: ";
for (int i = 0; i < num; i++)
{
cout << arr[i];
cout << " ";
}
cout << endl;
//Query user to quit or continue
cout << " Would you like to continue? Enter 'Q'. Enter anything else to continue.";
cin >> check;
}
return 0;
}
It is because you declared them inside an if/else block. Once the block completes, these variable go out of scope and are no longer accessible.
One way around this would be to always read in the input as character data, then convert it into the specified type after the fact. See atoi for how to convert from char to int.
A variable can never have unknown type. Even inside a template, the type of every variable is fixed for any particular instantiation.
Which suggests a solution. All the code that works on a variable with multiple types can be placed into a template function.
You may find the template syntax for passing an arbitrary length array of arbitrary element type useful:
template<typename T, size_t N>
void func1( T (&arr)[N] )
{
//...
}
But you really don't even need to pass the array. Just pass a type, and use that type when creating the array inside the function.
template<typename T>
void process_it()
{
T arr[100];
T input;
// now work on them
}
Either way, you'll need to call this function from inside all the if/else branches, where the exact type is known.