Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I've been told to read/write disc as little as possible. For this solution, I've made a constructor that reads the file on object construction and fills the unordered map with the contents of the file. Is this a good way/practice to read from .txt files?
In terms of printing out the contents of the file, I've mentioned readFile again. Is this ok to do? I couldn't really find another way without making it global. Here is the code below:
class Test {
private:
string name;
string number;
unordered_map<string, string> mappy;
public:
Test()
{
ifstream readFile("A:\\Coding\\namesNumbers.txt");
while (readFile >> name >> number)
{
mappy[name] = number;
}
}
void print()
{
ifstream readFile("A:\\Coding\\namesNumbers.txt");
while (readFile >> name >> number)
{
for (int i = 0; i < 1; i++)
{
cout << name << ":" << " ";
cout << number << endl;
}
}
}
~Test() {};
};
You are reading the file twice. When you don't mind the order of the items, then you can also print from 'mappy'.
Note that it is better to declare 'name' and 'number' as local as possible.
(Consider using another data type for 'number' i.s.o. 'string'.)
In the code below, I assume you have C++17 (for Structured binding)
class Test {
private:
unordered_map<string, string> mappy;
public:
Test()
{
ifstream readFile("A:\\Coding\\namesNumbers.txt");
string name;
string number;
while (readFile >> name >> number)
{
mappy[name] = number;
}
}
void print()
{
for (auto [name, number] : mappy)
{
cout << name << ":" << " ";
cout << number << endl;
}
}
~Test() {};
};
Reading a file in a construct is not necessarily a bad practice. Depends on the intended usage of the class. Sometimes you need to separate (default) construction from the reading of the data. In such a case you can provide two constructors: one for default construction and one for construction with file reading. As long as your solution satisfies, you can stick to that.
Related
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 last year.
Improve this question
Hi this is my first subject (question) at stack overflow i've tried an project about c++ classes at Code::Blocks but something went wrong
#include <iostream>
using namespace std;
class char1
{
public:
string charName;
float charLength;
void printName()
{
cout<<"char name is"<<charName;
}
};
int main()
{
int charNAME;
float charLENGTH;
cout<<"write your char's name"<<endl;
cin>>charNAME;
cout<<"write your char's length"<<endl;
cin>>charLENGTH;
char1 name;
char1 length;
name.charName=charNAME;
length.charLength=charLENGTH;
return 0;
}
when i run program it asks me char's name i write something, after it asks char's length
but program end there i cant do anything
here is picture for help
Some fixes for your code to show you how to use your class in practice (with some
c++ coding tips).
#include <string>
#include <iostream>
// using namespace std; <== don't do this
// https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice
//class char1
class Character // <== give classes clear names, makes code more readable
{
public:
std::string name;
float length;
// I understand you want to do this to test stuff.
// but from a design point of view printing is not something
// a character can do to himself
/*
void printName()
{
cout << "char name is" << charName;
}
*/
};
// bit offtopic but :
// if you want to add support for printing your character
// its more common to overload operator<< for streams like this
std::ostream& operator<<(std::ostream& os, const Character& character)
{
os << "Your character's name = " << character.name << ", and his/her length = " << character.length << "\n";
return os;
}
int main()
{
// int charNAME; in your class this is a string, be consistent.
// float charLENGTH;
// make an instance of the Character class
Character character;
std::cout << "Enter your char's name : "; // << endl; avoid using endl use "\n" if you want a newline
std::cin >> character.name;
std::cout << "Enter your char's length : "; // << endl;
std::cin >> character.length;
std::cout << "\n";
std::cout << character; // this will now call your overloaded << operator
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Say we are making an address book by creating a class AddressBook. We put a variety of tools in the class, including the option to add a member. If we use a structure to keep track of each person's information, it would look like this:
class AddressBook {
public:
AddressBook()
{
count = 0;
}
void AddPerson();
//More functions..
struct Entry_Structure
{
char firstName[15];
char lastName[15];
char idNumber[15];
};
Entry_Structure entries[100];
unsigned int count;
};
Then we could write the following for the AddPerson function:
void AddressBook::AddPerson()
{
cout << "Entry number " << (count + 1) << " : " << endl;
cout << "Enter subject's first and last name: ";
cin >> entries[count].firstName >> entries[count].lastName;
cout << "Please enter the subject's ID number: ";
cin >> entries[count].idNumber;
++count;
}
However, instead of using a structure for Entry_Structure, I used a class.
That is, class Entry_Structure instead of struct Entry_Structure.
What would I have to change in the program and the following function to make this work?
The only practical difference between class and struct is that, by default, class members are private, and struct members are public.
So:
struct Entry_Structure
{
char firstName[15];
char lastName[15];
char idNumber[15];
};
Is equivalent to:
class Entry_Structure
{
public:
char firstName[15];
char lastName[15];
char idNumber[15];
};
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I was taught in school that using cin/cout to get and show information to the user in a function was considered bad practice. I was told that all input/output should be done in the main function.
Is this true and why?
Typical for schools, this is an oversimplification. What was really meant was probably that
Input/Output should be separate from data processing.
This is easily illustrated by an example:
Wrong:
void doStuff() {
std::string input;
std::cout << "Please provide input: ";
std::cin >> input;
for (int i = 0; i < input.size(); i += 2) {
input[i] = ' ';
}
std::cout << input << std::endl;
}
int main() {
doStuff();
}
Much better:
std::string getInput() {
std::string input;
std::cin >> input;
return input;
}
std::string processData(std::string input) {
for (int i = 0; i < input.size(); i += 2) {
input[i] = ' ';
}
return std::move(input);
}
void printOutput(std::string const& s) {
std::cout << s << std::endl;
}
int main() {
auto input = getInput();
auto output = processData(input);
printOutput(output);
}
This way you can easily mock or test each of the functions separately, and it's much easier to for example add input validation right now.
std::string getInput() {
std::string input;
if (!(std::cin >> input)) {
throw std::runtime_error("Input problem!");
}
if (input.empty()) {
throw std::length_error("Input can't be empty!");
}
return input;
}
As a side note, main could also be written as:
int main () {
printOutput(processData(getInput()));
}
What your teacher is most likely about is to prevent code like
void add(void) {
int a, b;
cin >> a >> b;
cout << (a + b) << endl;
}
Which is often seen from beginner programmers. What is bad about this code is that it's on the one hand lying about what it does (because it doesn't add, it reads, adds and prints) and on the other hand misuses the most important abstraction tool, the function:
A function is intended to solve one task (which may be complex and consist of subtask) and more over - keeping to the mathematical origin of the term - act as a kind of transformation from some given parameters to some result, ideally like in purely functional languages without changing our having any state. (That is no matter when, how often and in what circumstances you call f(a), if you once get b as result you'll get that every time you call f with a)
Applying that to the simple example gives
int add(int lhs, int rhs) {
return lhs + rhs;
}
Nonetheless we somehow need to access the real world (which is very stateful), so for things like the following it's OK to have IO in a function:
int askInteger(void) {
int result;
cout << "Please give me an integer!";
cin >> result;
return result;
}
Please note that this is just an relatively stupid example, without any error handling or parametrisation.
To keep closer to the functional style it's advisable to not hard code the source and target of the IO like above, but rather pass them as parameters:
int askInteger(std::istream & from, std::ostream & to) {
int result;
to << "Please give me an integer!";
from >> result;
return result;
}
// called like
askInteger(cin, cout);
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
I've been debugging this for a long time now - but I have no clue what the issue is.
I get a name from the console (via std::cin) and then proceed to create a new Player object with it. Then I pass the new object to the Gameboard to be added to a std::vector<J> where J is part of a template. Here's the code:
main.cpp
Gameboard<Tile,Player,5,5> board = Gameboard<Tile,Player,5,5>();
std::string name;
std::cout << "Enter a name: "
std::cin >> name;
board.setPlayer(Player(name));
std::cout << std::endl;
std::cout << "Enter a name: "
std::cin >> name;
board.setPlayer(Player(name));
std::cout << std::endl;
std::cout << "Enter a name: "
std::cin >> name;
board.setPlayer(Player(name));
gameboard.h
template<class T, class J, const int X, const int Y>
class Gameboard {
std::vector<J> players;
public:
void setPlayer(J player);
};
template<class T, class J, const int X, const int Y>
void Gameboard<T,J,X,Y>::setPlayer(J p) {
////// DEBUG CODE //////
std::cout << p.getName() << std::endl;
players.push_back(p);
for (int i = 0; i < players.size(); i++) {
std::cout << players.at(i).getName() << std::endl;
}
}
player.h/player.cpp
class Player {
std::string name;
public:
Player(std::string _name);
std::string getName();
};
Player::Player(std::string _name) {
name = _name;
}
std::string Player::getName() {
return name;
}
I think I've tracked my problem down to the code marked DEBUG CODE. Using the above code, and entering the names Bob, Joe, and Tim, I would get the following output:
Enter a name: bob
bob
Enter a name: joe
joe
Enter a name: tim
tim
[exit]
So somehow, when I add the player to the vector, it becomes corrupted or something similar. The object is valid right before insertion because I echo out the name. The vector is also growing in size because it's printing blank lines equal to the number of players added.
What is going on?
You might have a copy constructor where you are not copying the name. So when you push_back on the vector, a Player object with empty name gets pushed on the vector.
Implement the copy constructor properly and it should work
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I made a program that should take input print it. Then run a simple addition thing but when i use spaces in the input it skips through the addition. I do not know what the problem is.
this is the class stuff
#include <iostream>
#include <string>
using namespace std;
class Cheese {
private:
string name;
public:
void setName(string x){
cin >> x;
x = name;
}
string getName(){
return name;
}
void print(){
cout << name << endl;
}
};
this is the main stuff
int main()
{
string h;
Cheese hole;
hole.setName(h);
hole.getName();
hole.print();
this part is getting skipped through without letting me input
int x = 5;
int y = 16;
cout << x+y;
num(x);
int a;
int b;
int c;
cout << "Type in a number and press enter.";
cin >> a;
cout << "Repeat.";
cin >> b;
c = a+b;
cout << c << endl;
if(c <= 21){
cout << "Good job!";
}
else {
cout << "You fail!";
}
return 0;
}
I suggest you divide the responsibilities a little differently. The Cheese class's setName function should simply take a string and set the instance's member variable to the given argument.
Then your program can read from standard input and populate a string within main, and pass that string to setName.
To be more concrete:
class Cheese {
private:
string name;
public:
void setName(const string& x){
// change this code to set the 'name' member variable
}
[...]
};
And the main becomes:
int main()
{
string h;
Cheese hole;
std::string input_name;
cout << "Type a name and press enter.";
cin >> input_name; // Will read up to first whitespace character.
hole.setName(input_name);
hole.getName(); // this is a no-op: compiler may warn of unused return value
hole.print();
In general, reading standard input as part of a class's interface is a bad idea, because it makes it hard to re-use that class in the future (for example, with programs that take input from a file instead of from a human at a console).
The input that you pass to cin input stream skips any white space, Tab space or newline. If you wish to input string then you can use cin.getline(string s). The input after the white space gets passed to next waiting cin, as the next cin accepts integer and it get a character string it skips that. Thus when enter a string with white spaces the program skips the remaining part.