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 8 years ago.
Improve this question
Evening All,
My following code:
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
const char NEWLINE = 0x0D + 0x0A;
int main() {
int headerCount;
char response;
int x = 0;
int i = 0;
string header[headerCount];
cout << "How many columns appear in you file: ";
cin >> headerCount;
cout << "There are " << headerCount << " columns in your file? (Y/N): ";
cin >> response;
if(response == 'Y'){
cout << endl << "Okay" << endl;
ofstream myfile;
myfile.open("example.csv", ios::binary | ios::out);
string vals;
vector< vector<string> > buff;
// To set values
while(i != 3){
vector<string> temp;
while(x != headerCount){
if (i == 0){
cout << "What is header number " << (x + 1) << endl;
} else {
cout << "What is person " << i << "'s " << header[x] << ":";
}
cin >> vals;
if (i == 0) header[x] = vals;
temp.push_back("\"" + vals + "\"");
if (x != (headerCount - 1)) { temp.push_back(","); }
x++;
}
buff.push_back(temp); // Store the array in the buffer
x = 0;
i++;
}
//To access values
for(vector<vector<string> >::iterator it = buff.begin(); it != buff.end(); ++it){
//it is now a pointer to a vector<int>
for(vector<string>::iterator jt = it->begin(); jt != it->end(); ++jt){
// jt is now a pointer to an integer.
myfile << *jt;
}
myfile << "\r\n";
}
myfile.close();
} else {
cout << endl << "oh";
}
return 0;
}
Crashes on its fourth iteration.
E.g. value[0][4]
Any ideas? I am reasonably new to vectors. This code causes Code::Blocks to display my application as "not responding". Really Lost at the moment!
I know there are probably plenty of similar posts but I have been trawling the web for hours.
First, you must thank #40two who quickly spotted the main issues.
So add the missing include. Then, define your variable header as a vector to allow for dynamic sizing. However, do this AFTER your cin reading, in order to make sure the variable is initialised and not random:
cin >> headerCount; // existing line
vector<string> header(headerCount); // definition in a new place
Then it should run without crashing (tested with VC2013)
As #40two mentioned, the real issue is that you cannot variable sized arrays in C++. There is huge scope to improve the code significantly. To get you going quickly, see the fixed up code below.
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
const char NEWLINE = 0x0D + 0x0A;
int main() {
int headerCount;
char response;
int x = 0;
int i = 0;
cout << "How many columns appear in you file: ";
cin >> headerCount;
cout << "There are " << headerCount << " columns in your file? (Y/N): ";
cin >> response;
if(response == 'Y'){
cout << endl << "Okay" << endl;
ofstream myfile;
myfile.open("example.csv", ios::binary | ios::out);
string vals;
vector< vector<string> > buff;
// To set values
while(i != 3){
vector<string> temp;
while(x != headerCount)
{
string header;
if (i == 0){
cout << "What is header number " << (x + 1) << endl;
} else {
cout << "What is person " << i << "'s " << header << ":";
}
cin >> vals;
if (i == 0)
header = vals;
temp.push_back("\"" + vals + "\"");
if (x != (headerCount - 1)) { temp.push_back(","); }
x++;
}
buff.push_back(temp); // Store the array in the buffer
x = 0;
i++;
}
//To access values
for(vector<vector<string> >::iterator it = buff.begin(); it != buff.end(); ++it){
//it is now a pointer to a vector<int>
for(vector<string>::iterator jt = it->begin(); jt != it->end(); ++jt){
// jt is now a pointer to an integer.
myfile << *jt;
}
myfile << "\r\n";
}
myfile.close();
} else {
cout << endl << "oh";
}
return 0;
}
Related
Here's my current code:
#include <iostream>
#include <set>
using namespace std;
int main()
{
string numOne, numTwo, numThree;
int pointOne, pointTwo, pointThree, totalPoint;
set<string> ansOne = { "TOE", "TONGUE", "TOOTH" };
cout << "Give A Body Part That Starts With The Letter T";
cout << "\n1. ";
cin >> numOne;
if (ansOne.find(numOne) == ansOne.end())
{
ansOne.erase(numOne);
cout << "Wrong!";
pointOne = 0 + 0;
}
else
{
cout << "Nice, You got a Point!";
pointOne = 1 + 0;
}
cout << "\n2. ";
cin >> numTwo;
if (ansOne.find(numTwo) == ansOne.end())
{
ansOne.erase(numTwo);
cout << "Wrong!";
pointTwo = 0 + pointOne;
}
else
{
cout << "Nice, You got a Point!";
pointTwo = 1 + pointOne;
}
cout << "\n3. ";
cin >> numThree;
if (ansOne.find(numThree) == ansOne.end())
{
ansOne.erase(numThree);
cout << "Wrong!";
pointThree = 0 + pointTwo;
}
else
{
cout << "Nice, You got a Point!";
pointThree = 1 + pointTwo;
}
totalPoint = pointOne + pointTwo + pointThree;
cout << "\n" << totalPoint;
}
What I want to do is, if the answer is after they put the answers, and if the word is in there, I want to erase that word from the set so they can't duplicate the answer. But it's not getting erased from the set.
Per your declared logic, you put the erase in the wrong branch of the if, only erasing a word when the word wasn't in the set already, and not erasing it when it was. The first if/else block would be fixed with:
if (ansOne.find(numOne) == ansOne.end())
{
// Removed ansOne.erase(numOne); here, because you just confirmed it's not in ansOne
cout << "Wrong!";
pointOne = 0;
}
else
{
ansOne.erase(numOne); // It's in ansOne, remove it so it can't be guessed again
cout << "Nice, You got a Point!";
pointOne = 1;
}
Similar changes would be made to the other two if/else blocks.
Note that this code would be much simpler with a for loop that runs three times and maintains the running total, rather than individual variables for each of three nearly identical tests. For example, the fixed version of your code could simplify to:
int main()
{
string userinput; // Just one string for input
int totalPoints = 0; // Just one score counter
set<string> ansOne = { "TOE", "TONGUE", "TOOTH" };
cout << "Give A Body Part That Starts With The Letter T";
for (int i = 1; i <= 3; ++i) {
cout << '\n' << i << ". "; // Number prompts dynamically
cin >> userinput;
const auto inputloc = ansOne.find(userinput); // Storing off iterator speeds erasure later (admittedly not meaningful for three element set
if (inputloc == ansOne.end())
{
cout << "Wrong!";
}
else
{
ansOne.erase(inputloc); // Erase with iterator to element found
cout << "Nice, You got a Point!";
++totalPoints;
}
}
cout << '\n' << totalPoint << '\n';
}
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.
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 "".
I am trying to write a program to find specific word in several sentences, but something went wrong when I tried to input a word, I've tried cin.ignore(),cin.sync() and cin.clear(), all not working.
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<string> svec;
cout << "please input text:(at most 10 lines): " << endl;
while(svec.size() < 10) {
string sentence;
getline(cin, sentence);
transform(sentence.begin(), sentence.end(), sentence.begin(), ::tolower);
svec.push_back(sentence);
if(cin.eof())
break;
}
// I tried to clean up cin here by
// cin.ignore() , cin.sync() and cin.clear()
// none of them work
string wordToFind;
cout << "please input the pattern: ";
cin >> wordToFind; // This line isn't working
// If I print out wordToFind, it contains nothing
transform(wordToFind.begin(), wordToFind.end(), wordToFind.begin(), ::tolower);
bool isFind = false;
int whichLine = 1;
for(vector<string>::iterator iter = svec.begin(); iter != svec.end(); iter++, whichLine++) {
size_t pos = 0;
while((pos = iter->find(wordToFind, pos)) != string::npos) {
cout << "Found at" << endl;
cout << "Line " << whichLine << " column " << pos++ << endl;
isFind = true;
}
}
if(isFind == false)
cout << wordToFind << " not found";
return 0;
}
I have no idea what is going on for cin, is that a problem of the cin buffer or other related issue?
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;