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.
Related
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.
I have a problem with my exercise code. If I enter the name and score value the values aren't getting pushed into the vector. Here is my code:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
while(true)
{
vector<string> names = {"test"};
vector<int> scores = {0};
string name = "none";
int score = 0;
cin >> name >> score;
if(name == "print" && score == 0)
{
for(int i = 0;i<names.size();++i)
{
cout << "name:" << names[i] << " score:" << scores[i] << "\n";
}
}
if(name == "NoName" && score == 0)
{
break;
}
if (find(names.begin(), names.end(), name) != names.end())
{
cout << name << " found name in names, you can't use this name.\n";
}else{
names.push_back(name);
scores.push_back(score);
}
}
}
the else-statement where the values are getting pushed in the vector is getting called but it doesn't push the values in the vector.
Your issue here is names and scores are declared inside the while loop. That means every iteration they are constructed, used, and then destroyed. This means in every iteration you have fresh vectors. You need to move the vectors out of the loop so they persist through the entire execution of the loop.
vector<string> names = {"test"};
vector<int> scores = {0};
while(true)
{
string name = "none";
int score = 0;
...
}
c++ Microsoft visual studio on a windows.
im very new to coding. currently going through Programming -- Principles and Practice Using C++ by Stroupstrup and I came across a difficulty. I am to create a "score chart" with vector name and vector score from the user input. I used for-loop to get the input. now I am to modify the program so that with 2nd input from the user I can search the list and "cout<<" the score for a person. the problem is the the program completely ignores the 2nd "cin>>" command.
I search online and could not find a reasonable answer to this problem. Is there any special interaction between a for-loop input being terminated and another input (not looped)
syntax:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> name;
vector<int> score;
string temp2;
int i;
for (string temp; cin >> temp >> i;) //input terminated with "Ctrl+Z"
name.push_back(temp), score.push_back(i);
for (int i = 0; i < name.size(); ++i) {
for (int j = i + 1; j < name.size(); ++j) {
if (name[i] == name[j]) {
name[j] = "error";
score[j] = 0;
}
}
}
for (int i = 0; i < name.size(); ++i) {
cout << name[i] << "------" << score[i] << "\n";
}
cout << "name"; //this line shows in the console
cin >> temp2; //but I cannot prompt the user to input again?
return 0;
}
CTRL-Z is interpreted as "End-Of-File", such that any subsequent access to this stream will not read in items any more. The only secure way is to change program logic such that the list of names is terminated by, let's say "END", and not a CTRL-Z. Then you can continue in a save manner.
Often input from a terminal is read in line by line and parsed afterwards. This makes error handling easier. See the following code following such an approach:
#include <sstream>
int main() {
string line;
map<string,int> scoreboard;
cout << "enter name score (type END to finish):" << endl;
while (std::getline(cin, line) && line != "END") {
stringstream ss(line);
string name;
int score;
if (ss >> name >> score) {
scoreboard[name] = score;
} else {
cout << "invalid input. Type END to finish" << endl;
}
}
cout << "enter name:" << endl;
string name;
if (cin >> name) {
auto item = scoreboard.find(name);
if (item != scoreboard.end()){
cout << "score of " << name << ":" << item->second << endl;
}
else {
cout << "no entry for " << name << "." << endl;
}
}
}
I am currently working on the assignment where I need to iterate through some student records. Each record has reg. number, name, and 0 to multiple module names with marks respectively.
I have a Student class and a Main class.
In the main class there's a function to iterate through a vector of Students and print the average grade.
Function to print average grades as well as names.
void aboveGiven(vector<Student> &students, float given) {
vector<Student>::iterator it;
for(it = students.begin(); it != students.end(); it++) {
if(it -> getAverageMark() >= given) {
cout << it->getName() << " " << setprecision(2) << it->getAverageMark() << endl;
}
}
}
Function to calculate average grade. "Given" parameter is the input used to define above what average to display the records. (in this case it is 70 meaning all the records with average above 70 have to be printed)
float Student::getAverageMark() const
{
if (marks.size() == 0)
return 0;
int count;
float sum;
map<string, float>::const_iterator it;
for (it = marks.begin(); it != marks.end(); ++it, ++count) {
sum += it->second;
}
return sum / count;
}
The massive problem I have is weird behaviour of cout where it prints nothing if I pass 60 or above as a "Given" parameter.
However the following code:
void aboveGiven(vector<Student> &students, float given) {
vector<Student>::iterator it;
for(it = students.begin(); it != students.end(); it++) {
cout << "a" << endl;
if(it -> getAverageMark() >= given) {
cout << it->getName() << " " << setprecision(2) << it->getAverageMark() << endl;
}
}
}
with only difference of line cout << "a" << endl;gives me following output:
a
a
a
Lisa Simpson 88.03
a
Homer Simpson 99.90
a
a
Wayne Rooney 75.45
a
a
a
a
Where 'a' corresponds to all the records with average grade below 70 and, as we can see all the records with average grade above 70 are now printed well.
Sometimes, when using different parameters for cout, only some of the outputs would be actually displayed but not all.
I am new to C++ and still am very confused with references and pointers, so I suspect there might be a problem with them. Otherwise could this be an issue with IDE ( I am using CLion which supports C++11).
I am sorry if this is not informative enough, have never posted anything here before. If you need any additional information please feel free to ask, I will post it.
classes just in case:
Student.cpp
using namespace std;
#include "Student.h"
#include <iostream>
Student::Student(const string& name, int regNo)
: Person(name)
{
this->name = name;
this->regNo = regNo;
this->marks = marks;
}
int Student::getRegNo() const
{
return regNo;
}
void Student::addMark(const string& module, float mark)
{
marks[module] = mark;
}
float Student::getMark(const string& module) throw(NoMarkException)
{
if (marks.find(module) == marks.end()) {
throw NoMarkException();
}
return marks[module];
}
float Student::getAverageMark() const
{
if (marks.size() == 0)
return 0;
int count;
float sum;
map<string, float>::const_iterator it;
for (it = marks.begin(); it != marks.end(); ++it, ++count) {
sum += it->second;
}
cout << fixed;
return sum / count;
}
And main: (at the moment it is really bad styled, sorry)
using namespace std;
#include <iostream>
#include <fstream>
#include <sstream>
#include "Student.h"
#include <vector>
#include <iomanip>
void aboveGiven(vector<Student>& students, float given)
{
vector<Student>::iterator it;
for (it = students.begin(); it != students.end(); it++) {
cout << "a" << endl;
if (it->getAverageMark() >= given) {
cout << it->getName() << " " << setprecision(2) << it - > getAverageMark() << endl;
}
}
}
int main()
{
char studentFileName[30];
char marksFileName[30];
vector<Student> students;
cout << "Enter the name of a file with Students: " << endl;
cin >> studentFileName;
ifstream studentFile;
string line;
studentFile.open(studentFileName, ios::in);
if (studentFile.is_open()) {
while (getline(studentFile, line)) {
istringstream iss(line);
int regn;
string firstName, lastName;
iss >> regn >> firstName >> lastName;
students.push_back(Student(firstName + " " + lastName, regn));
}
studentFile.close();
}
else {
cout << "Failed to open: " << studentFileName << endl;
}
cout << "Enter the name of a file with Marks: " << endl;
cin >> marksFileName;
ifstream marksFile;
string ln;
marksFile.open(marksFileName, ios::in);
if (marksFile.is_open()) {
while (getline(marksFile, ln)) {
int regn;
string module;
float mark;
bool studentFound = false;
istringstream iss(ln);
iss >> regn >> module >> mark;
for (auto& student : students) {
if (student.getRegNo() == regn) {
student.addMark(module, mark);
studentFound = true;
}
}
if (!studentFound) {
cout << "Student with Registration Number " << regn << was not found." << endl;
}
}
marksFile.close();
}
else {
cout << "Failed to open: " << marksFileName << endl;
}
for (auto& student : students) {
map<string, float> tempMap = student.getMarks();
map<string, float>::iterator it;
cout << setw(20) << student.getName() << ": ";
if (tempMap.size() == 0) {
cout << "N/A";
}
else {
for (it = tempMap.begin(); it != tempMap.end(); it++) {
cout << setw(5) << it->first << '(' << it->second << "); ";
}
}
cout << endl;
}
aboveGiven(students, 70);
}
Thanks in advance for your help!
You didn't initialize int sum and int count in Student::getAverageMark. Then no one knows what could they be. They must be int sum = 0; and int count = 0;
Sorry if this post isn't the best, I'm brand new to the site and coding in general. My programs take input like "Sam 16 Emily 4 Molly 19" and sorts it alphabetically, while keeping the ages the same. It works like a charm, unless you enter more than 5 pairs. After you enter 5, the following names are sorted fine, but the ages aren't the right ones. I'm not sure where the code is getting the numbers it's outputting. This is my code. I apologize for posting everything (~30 lines), but I really don't know where the issue is.
#include"../std_lib_facilities.h"
vector<string> name;
vector<int> age;
void read_pairs()
{
string n;
int v;
while (cin >> n >> v && n != "NoName") { // read string int pair
for (int i = 0; i<name.size(); ++i)
name.push_back(n);
age.push_back(v);
}
}
void write_pairs(string label)
{
cout << label;
for (int i = 0; i<name.size(); ++i)
cout << '(' << name[i] << ',' << age[i] << ")\n";
}
int find_index(const vector<string>& v, const string& n)
// find n's index in v
{
for (int i = 0; i<n.size(); ++i)
if (n == v[i]) return i;
}
int main()
try
{
cout << "Please enter your name/age pairs. When finished, enter 'No More'\n";
read_pairs();
vector<string> original_names = name; // copy the names
vector<int> original_ages = age; // copy the ages
sort(name.begin(), name.end()); // sort the names
for (int i = 0; i<name.size(); ++i) // update ages
age[i] = original_ages[find_index(original_names, name[i])];
write_pairs("\nSorted:\n");
keep_window_open("~");
}
catch (runtime_error e) {
cout << e.what() << '\n';
keep_window_open("~");
}
catch (...) {
cout << "exiting\n";
keep_window_open("~");
}
You have many problems in your code. I couldn't even get it to compile for a while.
In the first place, that for loop in read_pairs() is preventing you from storing any names in name. In the second place, you need to see if n in read_pairs() is the break signal before inputting the age - otherwise you will break cin, you will learn that later, as I know that you are using Bjarne Stroustrup's book - the same one I learned from. In the third place, your code was breaking in find_index() because you were calling i < n.size(); rather than i < v.size(); in your for loop. Finally, you may want to handle multiple instances of the same name so you don't get one age for it. I have implemented a simple way to do this by setting the value of v[i] to "" in find_index() before I returned the position of the name in the array - this way, you cannot get the age for that name more than once.
This is the working code, with some comments included. Feel free to ask if you don't understand something, but I think you understand enough to figure it out.
#include "stdafx.h"
#include"../std_lib_facilities.h"
vector<string> name;
vector<int> age;
void read_pairs()
{
string n;
int v;
while (true) { // read string int pair
cin >> n; // input name
if (n == "No") // if name is "No", break so we do not input a string for age
break;
cin >> v; // input age
// insert name/age into vectors
name.push_back(n);
age.push_back(v);
}
}
void write_pairs(string label)
{
cout << label;
for (int i = 0; i<name.size(); ++i)
cout << '(' << name[i] << ',' << age[i] << ")\n"; // output name/age pairs
}
int find_index(vector<string>& v, const string n)
// find n's index in v
{
for (int i = 0; i < v.size(); i++)
{
if (n == v[i])
{
v[i] = ""; // remove name in case two of same name
return i;
}
}
}
int main()
try
{
cout << "Please enter your name/age pairs. When finished, enter 'No More'\n";
read_pairs(); // read name/age pairs
vector<string> original_names = name; // copy the names
vector<int> original_ages = age; // copy the ages
sort(name.begin(), name.end()); // sort the names
for (int i = 0; i < name.size(); i++) // update ages
age[i] = original_ages[find_index(original_names, name[i])];
write_pairs("\nSorted:\n"); // write name/age pair
keep_window_open("~");
}
catch (runtime_error e) {
cout << e.what() << '\n';
keep_window_open("~");
}
catch (...) {
cout << "exiting\n";
keep_window_open("~");
}