Errors because of vector<string>? [duplicate] - c++

This question already has answers here:
why is string not declared in scope
(3 answers)
Closed 2 years ago.
Sorry for the spaghetti code, I don't have much experience with C++ (or coding in general for that matter) but here is my code... Also first time posting on stack overflow so apologies for improper formatting.
I have been scouring the internet for the last 4 hours. Please tell me this is a simple fix.
I have tried using std::vector ingredients.
//Program_2.h
#pragma once
#include <vector>
#include <string>
#include <iostream>
namespace sandwich
{
class SandwichMaker
{
public:
vector<string> ingredients;//<-- causing a few errors
int s = 0;
int Control();
void Menu(int &s, vector<string> &vec);
void PrintSandwich(vector<string> &vec);
private:
};
}
//Program_2.cpp
#include "Program_2.h"
using namespace std;
using namespace sandwich;
int SandwichMaker::Control()
{
SandwichMaker swm;
//vector<string> ingredients;
swm.Menu(swm.s, swm.ingredients);
while (swm.s > 0)
{
swm.Menu(swm.s, swm.ingredients);
}
system("PAUSE");
return 0;
}
void SandwichMaker::Menu(int &s, vector<string>& vec)
{
SandwichMaker swm;
cout << "Please choose what you would like to do and type the ingredient (1 and 2 only)\n (0 quit, 1 add ingredient, 2 remove ingredient, 3 make sandwich): ";
cin >> s;
string tempIngredient = "";
switch (s)
{
case 1://add
//cout << "Enter the ingredient you are going to add.\n";
cin.ignore();
getline(cin, tempIngredient);
vec.push_back(tempIngredient);
cout << " Ingredient has been added\n";
break;
case 2://remove
if (!vec.empty())
vec.pop_back();
else
cout << " Nothing has been added yet\n";
break;
case 3: //make the sandwich
swm.PrintSandwich(vec);
break;
default:
break;
}
}
void SandwichMaker::PrintSandwich(vector<string>& vec)
{
cout << "Your sandwich contains: ";
for (size_t i = 0; i < vec.size(); i++)
{
cout << i << ", " << vec[i] << endl;
}
}
cant post an images soo link? https://imgur.com/a/mK0UrEU of all the errors that are getting spit out because of vector.

Your using namespace std comes after your inclusion of Program_2.h, so the SandwichMaker class is defined without using namespace std being in effect.
You thus need to write std::vector, not vector, and std::string, not string.
Note: Do not try to "fix" this by applying using namespace std earlier - that's a bad idea and poor programming. See:
Why is "using namespace std;" considered bad practice?
PS:
You're repeating the word "Sandwich" a whole lot of times: sandwich::SandwichMaker{}.PrintSandwich() - aren't these too many sandwiches?
I know a guy who's a sandwich maker and he never prints sandwiches.
If you have a class named WhateverMaker - you often don't really need the class at all, and could settle for a nice Whatever class, and some functions which return Whatevers. See also this.

Related

c++ obect out of scope inside a switch statement

The object derm is out of scope in the switch statement.
I tried to make it a static member function.
Is there anyway I can make this work?
Here is my code:
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <ctime>
using namespace std;
class Invinq {
int menu_pick;
string db_read_out;
public:
Invinq();
void menu_maker();
int add_record();
int change_record();
int delete_record();
int display_record();
int exit_program();
};
Invinq::Invinq()
{
cout <<"Welcome to Inventory Inquisator.\n********************************\n" << endl;
ifstream db_invinq;
db_invinq.open("Invinq_db.txt");
if(!db_invinq)
{
cout<<"\nNot able to create a file. MAJOR OS ERROR!! \n";
}
for(int i = 0; i < db_invinq.eof(); i++)
{
db_invinq >> db_read_out;
cout << db_read_out;
}
}
//Menu maker
void Invinq::menu_maker()
{
cout << "1. Add Record\n2. Change Record\n3. Delete Record\n4. Display Record\n5. Exit\n\nPick One: ";
cin >> menu_pick;
switch(menu_pick)
{
case 1: derm.add_record(); break;
case 2: derm.change_record(); break;
case 3: derm.delete_record(); break;
case 4: derm.display_record(); break;
default: cout << "Pick a number between 1-5, try again\n";
}
derm.menu_maker();
}
int main() {
Invinq derm;
derm.menu_maker();
return 0;
}
You seem to have completely missed the point. you don't need derm when you are already inside the Invinq class - just call menu_maker().
Having said that: you are using recursion for no good reason. This can have some unexpected side effects. I suggest you refactor menu_maker() - if fact right now there is no way to get out of the recursion, so that is really bad!
You main should have the loop and create a Invinq each time through, otherwise you are just overwriting the same object each time which is probably now what you want.
Inside the definition of your class method, you should refer to yourself using the keyword this.
Replace all the method calls as following:
case 1: derm.add_record(); break; > case 1: this->add_record(); break;
Note: this returns a pointer to your object, this is why we use -> rather than .

Why do I get an out_of_range exception here?

Currently doing a project at uni where at first I need to de-hyphenate a string, seemed pretty simple however when i run the program it has an error WeirdPuncProgram.exe: Microsoft C++ exception: std::out_of_range at memory location 0x004EF898
It also is not returning the string value properly, inside the function answer() is changed and hyphens are removed but once it comes out its just the original input again.
#include <iostream>
#include <string>
using namespace std;
string answer;
string hyphonRemover(string answer)
{
string spacer = " ";
int h;
for (int i = 0; i < answer.length(); i++)
{
h = answer.find_first_of("-");
answer.replace(h, 1, spacer);
}
return answer;
}
int main()
{
cout << "Type a sentence which contains punctuation and ill remove it for you! " << endl << endl;
getline(cin, answer);
hyphonRemover(answer);
cout << answer << endl;
system("pause");
return 0;
}
every use of answer in hyphonRemover() will be local variable, not global answer you defined above.
thus the function will modify only its local variable.

Why can't compare two strings in if condition? [closed]

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 7 years ago.
Improve this question
Why can't compare two strings in if condition?
#include <iostream>
#include <string.h>
using namespace std;
int main() {
string sexo[20], feminino;
feminino = "f";
for (int i = 0; i < 3; i++) {
do {
cout << endl << "enter your " << i + 1 << "sexo: ";
cin >> sexo[i];
if (strcmp(sexo[i], feminino)==0){ // problem in here
cout << "that's ok" << endl;
}
} while (nome[i] == "0");
}
return 0;
}
You've been reading "tutorials" for C, or "tutorials" for C++ that actually teach you a terrible and outdated mix of C and C++.
The function strcmp is from the C Standard Library, and does not operate on the C++ std::string type.
To compare two std::strings, simply write:
if (sexo[i] == feminino) {
I find it hard to believe that your C++ book does not teach you this.
These are a few correct ways to compare these strings (in reverse order of preference)
if (strcmp(sexo[i].c_str(), feminino.c_str()) == 0) {
if (sexo[i].compare(feminino)) == 0) {
if (sexo[i] == feminino) {
You are using the wrong compare function. What you are using works with char * (it is used in C) but here you have std::string so you have to use std::string::compare()
Change your code to this:
#include <iostream>
#include <string.h>
using namespace std;
int main() {
string sexo[20], feminino; // problem in here
feminino = "f";
for (int i = 0; i < 3; i++) {
do {
cout << endl << "enter your " << i + 1 << "sexo: ";
cin >> sexo[i];
if (sexo[i].compare(feminito) == 0){
cout << "that's ok" << endl;
}
} while (nome[i] == "0");
}
return 0;
Note that you can also use sexo[i] == feminito as you have relational operators for std::string (see here for examples)

Wondering about scope in C++ with structures and functions

I'm writing a program that allows me to put my name in and pull up different semesters and for me to put grades in and then be able to calculate my class average and GPA, just for my own reference in my courses.
What I am having a problem with is with structures and how they work with a multifunction program. In my courses we have not covered this and I have spent a while now searching for answers and cannot find one. Below is my current code:
using namespace std;
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char gettingName();
class Student{
public:
double semesterClass[20][20]; //first is for semester, second is for which class
char name[20];
int semester;
int numOfCourses;
};
int main(int argc, char **argv)
{
Student info;
gettingName();
cout << "Hi my name is: " << name.info << endl;
return 0;
}
char gettingName()
{
Student info;
char YesNo[5];
char boolean[1] = {'T'};
char yes[3] = {'Y','e','s'};
char yes2[3] = {'Y','E','S'};
char yes3[3] = {'y','e','s'};
char yes4[1] = {'Y'};
char yes5[1] = {'y'};
while(boolean[0] == 'T'){
cout << "What is your name? ";
cin >> info.name;
cout << endl;
cout << "Is your name " << info.name << "?"<<endl; //accepted input will be Y,y,YES,Yes,yes
cin >> YesNo;
//if input does not equal any of the accepted inputs, then loop until it does
if((strcmp(YesNo,yes) == 0) || (strcmp(YesNo,yes2) == 0) || (strcmp(YesNo,yes3) == 0) || (YesNo[0] == yes4[0]) || (YesNo[0] == yes5[0])){
boolean[0] = 'F';
}
}
return 0;
}
My question: how might I go about fixing the scope so that I can call the 'gettingName' function, get the person to input their name, (get it right (that already works)) and then be able to access and print it in the main function?
There are a lot of issues with your code, but I will try to help out the best I can. In general C++ scope for local variables is at the block level. So any time you see a ending bracket }, the scope has ended.
Some specific issues with your code that I noticed:
This line should be: "cout << "Hi my name is: " << info.name <<
endl;", not name.info
The boolean loop can be handled much more efficiently. You should try to list all of the acceptable options in one data structure like an array and then loop through the array.
Lastly when creating a function that doesn't need to return anything,
you can use the type void instead of char. So it could be void gettingName(), instead of char gettingName().
As an example to show you a quick and easy way to do what I think you wanted, I simplified your code a bit. I also decided to use std::string rather than char arrays as they are easier to work with:
class Student{
public:
std::string name;
};
std::string gettingName();
int main()
{
Student Info;
Info.name = gettingName();
cout << "Hi my name is: " << Info.name << endl;
return 0;
}
std::string gettingName()
{
std::string name;
cout << "What is your name? ";
cin >> name;
cout << endl;
return name;
}
Your code not really is object oriented. To fix the scope, you'll have to put gettingName inside your class to make it a member function (which is btw the term to Google for). You will also have to change the implementation which then needs to include the class name for identification:
char Student::gettingName()
{
...
}
From main you'd call it then via
info.gettingName();

cin.get() issue with empty line

When I run the following code and insert a new line (press enter) when prompted for
the golf structure, the second call to the function doesn't request input and finishes as if I've pressed enter again.
I've read up on : cin.get() , cin.clear() , cin.ignore(...) but nothing seems to help.
I'm pretty sure that it has nothing to do with multiple .cpp files and the header but I'm putting the code as is.
I'm using Visual Studio C++ 2010 - Express.
Thanks in advance for your help!
header file : golf.h
#ifndef GOLF_H
#define GOLF_H
const int Len = 40;
struct golf{
char fullname[Len];
int handicap;
};
int setgolf(golf & g );
void showgolf(const golf & g );
#endif
golf.cpp
#include "stdafx.h"
#include "golf.h"
#include <iostream>
#include <string>
using namespace std;
int setgolf(golf & g ){
cout << "Enter a name for the golf structure:" << endl;
if (cin.get(g.fullname,Len)) {
cin.get(); // deals with the '\n' incase the user inputs a valid string
return 1;
}
else{
return 0;
}
}
void showgolf(const golf & g ){
cout << "this golf structure contains the following information:" << endl;
cout << "name: " << g.fullname << endl ;
cout << "handicap: " << g.handicap << endl ;
}
main ()
#include "stdafx.h"
#include "golf.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
golf myGolf;
// check of int setgolf(golf & g );
int answ = setgolf(myGolf); //try to input empty string
showgolf(myGolf);
cout << "the number returned :" << answ << endl ;
answ = setgolf(myGolf); // normal string
showgolf(myGolf);
cout << "the number returned :" << answ << endl ;
return 0;
}
This problem happens when you just press enter in the first prompt. The input stream is marked as eof, an error condition flag (that's why it returns 0). The input stream then stops working.
It seems that you're using a kind of old C++, pre ISO 1998, while I don't think you need that. However, if you want to stick with your approach, then do the following: after cin.getline() (no need to return anything) write: cin.clear(); cin.sync();, as follows:
void setGolf(Golf &g)
{
cout << "Enter a name for the golf structure:" << endl;
getline( cin, g.fullname ) );
cin.clear();
cin.sync();
}
Now, about modernizing your code. First of all, you can use the standard library's class string, which is able to store a string literal, even growing if needed, without giving a maximum value of chars. This is somewhat confusing, since you are including the header string, which will include that class, but you're not using it. The use of string also comes with other advantages, such as automatically correcting the potential buffer overflow which could happen in your Golf structure. So I would change your structure to be:
struct Golf{
string fullname;
int handicap;
};
Now you can use getline(), in utility, which reads a whole line and stores it in string, doing all the magic for you. So you could change your golf.cpp file, to:
#include <utility>
//...
void setGolf(Golf &g)
{
cout << "Enter a name for the golf structure:" << endl;
getline( cin, g.fullname ) );
}
You can now also change the return type to void. It is not probable to experience an error of any kind while using getline(). Anyway, take into account that you could return bool (boolean type), which is a built-in type, with literals true and false.
I am certain that you could change your main() now, to a simpler style:
int main()
{
Golf myGolf;
setGolf(myGolf);
showGolf(myGolf);
setGolf(myGolf);
showGolf(myGolf);
return 0;
}
Finally, you could consider encapsulating your information in a class, instead of a struct, but that is a whole different issue.
Hope this helps.
You can also leave char[] instead of replacing it with string(I am still learning, so if I'm wrong please correct me). I think that when
std::cin.get(char *,Size) is not able to load characters, it's turning 2 bits on 0, fail and error, this is my solution:
std::cin.get(g.fullname, Len);
if(!std::cin)
{
std::cin.clear();
std::cin.get();
std::cout << "You inserted empty line." << std::endl;
return 0;
}