I've recently made a short a program about a new lesson that I've learned online about programming(which I'm a beginner in)C++, which I do every time I learn a new concept, to be in-depth with the concept of it and it's uses.(Its how I teach myself in programming). I used vector in my program and it solved my problem. But, it created a new one.
(You might have already seen this code)
#include <iostream>
#include <string>
#include <windows.h>
#include <vector>
using namespace std;
int main()
{
string LetterInput, LetterLoad, input;
string Words[5] = {"fire","eggs","roll","camera","lotion"};
vector <string> PossibleAnswers;
int Number,a = 0;
int Size,Num;
cout << "Lets play HANGMAN! " << endl;
Sleep(500);
cout << "Think of a word and type in the number" << endl;
cout << "of letters there are" << endl;
cin >> Size;
for (int i = 0; i <= Size; i++){
LetterLoad += "_";
}
Num = sizeof(Words)/sizeof(string);
for (int i = 0; i <= Num ; i++){
if ((unsigned)Size == Words[i].size()){
PossibleAnswers.push_back(Words[i]);
}
}
for (int i = 0;i <= Num;i++){
cout << PossibleAnswers[i] << endl;
}
cout << "Okay lets start" << endl;
Sleep(750);
while(a == 0)
{
cout << PossibleAnswers[0] << endl;
cout << PossibleAnswers[1] << endl;
cout << LetterLoad << endl;
cout << "Type in the position of the letter you want to guess" << endl;
cin >> Number;
cout << "What letter do you want to put?" << endl;
cin >> LetterInput;
LetterLoad[Number-1] = LetterInput[0];
for (size_t i = 0; i <= PossibleAnswers.size(); i++){
for (int n = 0; n <= Size; n++){
if (LetterInput[n] == PossibleAnswers[i][n]){
cout << "Got one" << endl;
}
}
}
}
return 0;
}
The program was able to take the right words. But, it stops working when it is about to reach the cout << "Okay lets start" << endl; and then everything below that line of code. I have heard that vectors require "memory allocation" from other people. Does that have something to with the program not running properly? and how do I fix it?
If the condition if ((unsigned)Size == Words[i].size()){ is not met for any number of cases, then you won't have pushed back enough strings. When that happens, you get a crash in the following for (int i = 0;i <= Num;i++){ loop because you're trying to access more element that you have. I would recommend doing this instead:
for (std::string &s : PossibleAnswers){
std::cout << s << std::endl;
}
You can also do a loop from 0 to PossibleAnswers.size(), like you do further below.
I have heard that vectors require "memory allocation" from other
people.
Nah, you must have misunderstood something. This was just an out of range error, I recommend to avoid those by always looping though vectors using range based for loops or by looping from 0 to vec.size().
You are asking questions about: I am trying to write an essay, but in fact, you don't know the alphabet. In my experience as a teacher, it's better to learn the programming basics first, rather than learning programming with libraries. This statement from you proves my opinion:
I have heard that vectors require "memory allocation" from other people.
Learn the different types of memory blocks. It is necessary for every programmer.
std::string
std::vector
These are linear data structures - don't use them, if you cannot implement them by yourself.
while (a==0) ...
You are allocating 4 bytes (in most architectures nowadays) for variable, which you don't even use it. Most of the compilers will change that code to:
while (true) ...
Because it is equivalent to it.
Everytime someone writes a magical number - a kitty around the world dies. Don't use magical numbers, save a kitty. Even in training sessions. You had time to write the description to the console, but you didn't make a const variable for the size of the array of strings.
It is good that you are motivated to learn programming. But if you are learning it wrong, there won't be any good results. My advice is to change the source, which you are learning from.
Related
I need some help trying to figure out a way to make an if statement taking the users input after a category is typed in. If the user types in string categories[0] in the cin statement, which in this case is "Number of drivers involved in fatal collisions per billion miles." I want it to display the first sentence from the worststate[0] array, which in this case will be North Dakota and South Carolina. I need help doing that for every category, to match up with the state listed, it goes in order.
#include <iostream>
using namespace std;
string worstState[7] = {
{"North Dakota and South Carolina"},
{"Hawaii"},
{"Montana"},
{"District of Columbia"},
{"District of Columbia and Mississippi"},
{"New Jersey"},
{"Louisiana"},
};
void displayIntro(){
cout << "Welcome to the Car Accident Statistic Website" << endl;
cout << "Take a look at the following categories: " << endl;
}
string categories[7] = {
{"Number of drivers involved in fatal collisions per billion miles"},
{"Percentage of drivers involved in fatal collisions who were speeding"},
{"Percentage of drivers involved in fatal collisions who were Alcohol-Impaired"},
{"Percentage of drivers involved in fatal collisions who were not distracted"},
{"Percentage of drivers involved in fatal collisions who had not been involved in any previous accidents"},
{"Car Insurance Premiums"},
{"Losses incurred by insurance companies for collisions per insured driver"},
};
int main(){
string Input;
displayIntro();
cout << categories[0] << endl;
cout << categories[1] << endl;
cout << categories[2] << endl;
cout << categories[3] << endl;
cout << categories[4] << endl;
cout << categories[5] << endl;
cout << categories[6] << endl;
cout << "Enter a category: ";
cin >> Input;
if (Input == categories....
return 0;
}
Obviously the code isn't the best organized, which I'm still gonna work on, but I just want the user to type in the category string, and for the state to match up with that specific category in the categories array, all in order based on the way they are entered.
Wondering what the best way to go about this situation is
You can use an unordered_map (aka hash table):
Initialize the map at the start of your program that maps all the questions to their respective answers (i.e. categories[i] to worstState[i]).
unordered_map<string, string> questionsToAnswers;
for (size_t i = 0; i < 7; i++) {
questionsToAnswers[categories[i]] = worstState[i];
}
When the user types a string in, you can look up the answer like this:
string s;
cin >> s;
auto itor = questionsToAnsers.find(s);
if (itor != questionsToAnswers.end()) {
cout << itor->second;
} else {
// question not found in map
}
If I understand correctly if the user inputs in categories[0], you want to display worstState[0], if the user inputs in catergories[1], you want to display worstState[1], and so on. Now it looks like your input is fixed which means you can use a switch statement, however because there are a fairly large number of courses you want to consider a for loop probably would look more clean.
So something like:
for(int i = 0; i < size(categories); i++){
if(Input == categories[i]){
cout << worstState[i] << endl;
}
}
Been trying to find a way through this. I am new to C++ and creating a simple program to get the user data, validate and cout to the screen. What i'm trying to do is to have the one function use pointers to get the users input and display back to them. This may have been answered before but I haven't had much luck finding it.
So far i have the below code
#include <iostream>
using namespace std;
void userData(int&);
int main(){
int a = 0;
int * kmpointer;
int * dayspointer;
userData();
cout << "You ran " << userData(kmpointer) << endl;
cout << "in " << userData(dayspointer) << "days!!" <<endl;
}
void userData(int& i){
cout << "Enter how Many Km's you ran:";
while (true)
{
cin >> kmpointer;
if ((cin) && (kmpointer >= 0) && (inputYear <= 100))
break;
cin.clear();
cin.ignore( 100, '\n' );
cout << "That can't be right!\n";
cout << "Enter how Many Km's you ran:";
}
cout << "How many days in a row did you run?";
while (true)
{
cin >> dayspointer;
if ((cin) && (dayspointer >= 1) && (dayspointer <= 100))
break;
cin.clear();
cin.ignore( 1000, '\n' );
cout << "Thats way to much!";
cout << "How many days in a row did you run? ";
}
}
IMO, you should start with some reading about C++. You are missing some basic concepts and trying too complex exercises for your level.
1
function is not declared/defined.
2
userData is declared accepting a parameter, but used without.
3
The problem you face is related probably with what we call scope: A variable is only existing and visible within its scope (usually enclosed by { and }.
In your case, kmpointer and dayspointerare only visible within the main function and thus, you cannot use them in userData.
To solve that, I suggest you to pass those variables as parameters for userData.
4
Pointers, references, values: They are different. You are saving the user input as a pointer address, which is indeed problematic.
General
In general, your code is full of mistakes. Try a Hello world! and continue from there steps by steps.
Focussing on the specific question you asked (though as observed you have other problems in your code), don't use pointers, use references.
Before we get to that this
cout << "You ran " << userData(kmpointer) << endl;
won't compile, since as you know userData is a void function, so applying << to it makes no sense. It's void so there's nothing to stream.
You said you wanted to pass parameters into the function and let them be changed so do that. Then display the variables afterwards. (Not the "result" of a void function call).
Correctly getting the user input is a separate question which has been answered before.
#include <iostream>
using namespace std;
void userData(int& i, int& j, int& k);
int main() {
int a = 0;
int kmpointer;
int dayspointer;
//Here we call our function, ONCE
userData(a, kmpointer, dayspointer);
//Here we display what values we now have
//after calling the function, ONCE
cout << "You ran " << kmpointer << endl;
cout << "in " << dayspointer << " days!!" << endl;
}
//simplified to demonstrate changes to the reference parameters
void userData(int& i, int& j, int& k) {
//Here we have three parameters which we refer to as i, j and k
// They may have different names ousdie in the calling code
// but this function (scope) neither knows nor cares
j = 42;
k = 101;
}
I have been making a program for a local... place, and it is a program that will calculate how much pizza will should be ordered. The problem, however, is not even the calculations, but rather with the files that keep log-in I.D. data.
#include <iostream>
#include <stdlib.h>
#include <iomanip>
#include <fstream>
using namespace std;
string logs[20];
void test(ifstream& IN, string logs[], ofstream& OUT);
void introduction();
int logging_in(string id, string logs[]);
void menu();
string newl = "\n";
string dnewl = "\n\n";
string tnewl = "\n\n\n";
string qnewl = "\n\n\n\n";
string pnewl = "\n\n\n\n\n";
int main()
{
ifstream IN;
ofstream OUT;
string id;
IN.open("loginn.dat");
cout << IN.is_open();
test(IN, logs, OUT);
string sup;
int receive = 0;
introduction();
return 0;
}
void test(ifstream& IN, string logs[], ofstream& OUT)
{
for (int x = 0; x < 20; x++)
{
IN >> logs[x];
}
IN.close();
OUT.open("loginn.dat");
for (int x = 0; x < 20; x++)
{
OUT << logs[x] << " " << "hue" << " ";
}
}
void introduction()
{
string cont;
cout << "Hello. I am the..." << dnewl
<< "Statistical" << newl << "Pizza" << newl
<< "Order" << newl << "Amount" << newl
<< "Diagnostic." << dnewl
<< "Otherwise known as Pizzahand. I will be assisting you to estimate the \namount of pizza that is to be ordered for <INSERT NAME>, as to \neliminate excessive ordering."
<< tnewl;
cout << "Press Enter to continue..." << newl;
cin.get();
}
In theory this is supposed to output the array "logs[]" before executing the rest of the code. This was the case when I had no functions in addition to the main function. As soon as I started to use my next function, "introduction()", the code for reading the text file here
for (int x = 0; x < 20; x++)
{
IN >> logs[x];
}
seemed to be knocked out of order. Instead of performing this task before anything else, it seems as if it does it at the very end of the program as I have tested by outputting its contents while the program was still reading "test()", with no luck. After the main function returns "0", however, I see that my program has outputted data into a test file, "loginns.dat", properly.
It is imperative for my program that this login ID data gets read in at the beginning as when the program transitions to logging in, the data is needed. Also, I have tried placing these arrays and for loops in different locations: in the log-in functions themselves, in the main function, and even another function that I created out of desperation.
I have searched for hours on how to solve this to no avail and experimented myself for plenty of hours more. Every step I took to attempt to fix this lead to more dead ends, or more questions. I am quite the beginner in the sense that this school-year is the first year of studying c++, and I am desperate for an expert opinion (or anyone knowledgeable) to help me face the right direction.
Thank you.
You just need to flush the stream after writing to it:
for (int x = 0; x < 20; x++)
{
OUT << logs[x] << " " << "hue" << " ";
}
OUT.flush();
The reason for this strange behaviour is that file streams don't necessarily write out to files immediately when you write to them. For efficiency reasons, they write the data to an internal memory buffer (an area of memory used by the stream), and then write the buffer contents out to the file all at once when the buffer is flushed. When an application finishes then all of its stream buffers are automatically flushed, which is why you are seeing that the file has been written to after your program finishes. However you can flush them earlier yourself, as shown above. It can also happen when the buffer gets full.
You can also trigger a flush using the endl token, which writes a newline character and flushes the buffer, like this:
for (int x = 0; x < 20; x++)
{
OUT << logs[x] << " " << "hue" << " " << endl;
}
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I'd like to know if I am in fact in the right direction, I am currently learning the C++ language and reading this book called Jumping into C++ by Alex Allain and there's a practice problem at the end of the chapter regarding structures, to create a contact book program the user should be able to not just fill out a single structure, but should be able to add new entries, each with a separate name and phone number. Let the user add as many entries as he or she wants—is this easy to do? Add the ability to display all, or some of the entries, letting the user browse the list of entries.
so far below is what I've done, I'd like to know if my source code is in fact right and does it show my understanding about structures and overall c++?
#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
struct user{
string name;
int phone_num;
};
int _tmain(int argc, _TCHAR* argv[])
{
int input, number; // will hold the users input at the beginning of the program
int counter = 0; // keep track of the array position
int const arraySize = 10; // size of the array
user new_username[arraySize]; // will hold the users details
string name; // will hold the users input for the name
cout << "CONTACTS\n";
do{
cout << "+ADD [1] -EXIT[0]";
cin >> input;
if(input == 1){
//cout << counter;
cout << "\nName: ";
cin >> name;
new_username[counter].name += name;
cout << endl << "\nPhone: ";
cin >> number;
new_username[counter].phone_num = number;
counter++;
//set_user(counter);
}
cout << "Name Number\n";
cout << "--------------\n";
for(int j=0; j < arraySize; j++){
cout << new_username[j].name;
cout << " -- ";
cout << new_username[j].phone_num;
cout << "\n";
}
cout << "\n";
}while(input != 0);
cout << "\n";
system("PAUSE");
return 0;
}
Stackoverflow isn't meant to be used for code reviews, but there's a different site for this (although still in beta): https://codereview.stackexchange.com/
Just some quick things I noticed:
Your program ignores invalid input (enter 2, 3 or any other number instead of 1 or 0).
You don't check whether your user array is full.
This is not really object oriented.
As for basic understanding... I guess yes, but that's not actually hard to start with.
To fulfill "allow the user to add as many entries as they want" you'll have to use a dynamic array (ask the user how many entries he'd like to add) or use some dynamic storage (e.g. a linked list).
If you want the user to be able to add as many contacts as he/she wants, you can use powerful standard template mechanisms.
For this application, I would recommend looking at either
std::vector
or
std::map
This is how you would use them: (keep in mind this is pseudo code and won't compile)
#include <vector>
typedef struct {
std::string name;
double phoneNumber;
} YourStruct;
int main( int argc, char **argv ) {
std::vector<YourStruct> structVector;
do {
int input;
std::cin >> input;
if (input) {
//(read user input for name and number)
YourStruct yourStruct;
yourStruct.name = (user input)
yourStruct.phoneNumber = (user input)
// insert into the vector
structVector.push_back(yourStruct)
}
} while (input != 0)
// now to print what you have:
for (int i = 0; i < structVector.size(); i++) {
std::cout << structVector[i].name << ", " << structVector[i].number << std::endl;
}
}
The benefit to using vectors is that it automatically resizes and keeps track of how large it is without you having to use a counter item.
Now, for something a bit trickier. We're going to use a map to use the "key" value to get the name. The following code won't compile but it is functionally how you would perform the task:
#include <map>
int main(int argc, char** argv) {
std::map<std::string,double> myMap;
// the string is the "key" value, which can be the name of the person
// while the "independent" is the phone number
do {
// determine if the user wants to put another entry in the map
if (insert) {
std::string name = (user input name)
double number = (user input number)
myMap[name] = number;
}
} while (input != 0)
// now we can iterate through the map
std::map<std::string,double>::iterator it;
for (it = myMap.begin(); it != myMap.end(); ++it) {
std::cout << it.first << ", " << it.second << std::endl;
}
// also, you can look up by name
it = myMap.find("Tony Stark");
if (it != myMap.end()) { // if this condition is met, it means you found one
std::cout << it.first << ", " << it.second << std::endl;
}
}
Overall, your code looks good. However, it is not C++. You're programming like a C programmer. The beauty of C++ (besides polymophisim, of course) is the powerful template libraries.
I've just given you a small taste of what you can do with templates. Please comment if you have any questions of concerns. We've all been where you are, kudos for teaching yourself out of a book.
From your question and the code it seems like you are a new programmer, therefore I'll explain you the answer and I'll give you some notes on your code.
In order to solve the problem of "as many items" there are few approaches. The most easy one, and probably a pretty good solution is to use map, in any language it have different names. But usually the name is dictionary, associative arrays...
Using the map will help you with dealing with:
As many items
Sorted order by name
It will be easier for you to filter, it depends what you would like to do, and how sophisticated is your filter.
The other approaches I talked about i though of, are much more basic, and consist much more code, but they give you the feeling of how you can implement the map object by yourself, but this is a different question.
In the link I mention above, the example is for phone entry. But if you still want to use struct, you can have the key as the name and the value to be the struct itself. One justification for that can be that later on you plan to add address and company name.
Some notes regarding your code.
#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
//use meanigful name, instead of user it can be phoneEntry
struct user{
string name;
//Starting using the following conventions using the capital letter in variable names for example phoneNumber
//int won't be god for phone number since some times you will need star or hash, or a leading zero, maybe a plus sign. It is better touse string for tat as well. And of course every time that you get a user input you should validate it
int phone_num;
};
//Why the name of the function is not main, why its _tmain
int _tmain(int argc, _TCHAR* argv[])
{
//Keep going with your comments, with time you would imbrase your own style based on things that you will see. But in general commenting is very important
//Give meanigful name, instead input userCommand for example
int input, number; // will hold the users input at the beginning of the program
int counter = 0; // keep track of the array position
int const arraySize = 10; // size of the array
//Again meangful names
user new_username[arraySize]; // will hold the users details
string name; // will hold the users input for the name
cout << "CONTACTS\n";
do{
cout << "+ADD [1] -EXIT[0]";
cin >> input;
if(input == 1){
//cout << counter;
cout << "\nName: ";
cin >> name;
new_username[counter].name += name;
cout << endl << "\nPhone: ";
cin >> number;
new_username[counter].phone_num = number;
counter++;
//set_user(counter);
}
cout << "Name Number\n";
cout << "--------------\n";
for(int j=0; j < arraySize; j++){
cout << new_username[j].name;
cout << " -- ";
cout << new_username[j].phone_num;
cout << "\n";
}
cout << "\n";
}while(input != 0);
cout << "\n";
system("PAUSE");
return 0;
}
I hope it helped
I'm new to C++, and right now I'm learning from the book called Accelerated C++. I finished the third chapter (vectors), and I came to this exercise:
"Write a program to count how many times each distinct word appears in its input."
After some thinking, I started working on it. I wanted to test the program, but std::cout wasn't working. I put cout << "test"; on a few places in my code to see where's the problem, and the conclusion is that it doesn't work inside the first for-loop. Don't recommend me to use maps to solve the problem, because I'm working on vectors. The variables aren't in English, so I'll translate some for you to know what's going on:
recenica - the sentence; rijec - a word; vel_vektora - size of the vector; duz_recenice - length of the sentence; br_ponavljanja - number of times a word appears in the sentence;
#include <vector>
#include <iostream>
#include <string>
using std::string; using std::vector;
using std::cin; using std::cout;
using std::endl;
int main()
{
string rijec;
vector<string> recenica;
while (cin >> rijec) recenica.push_back(rijec);
cout << endl;
typedef vector<string>::size_type vel_vektora;
vel_vektora duz_recenice = recenica.size();
cout << "test0, ";
for (int i = 0; i < duz_recenice - 1; ++i)
{
cout << "test, !";
int br_ponavljanja = 1;
for (int j = i + 1; j < duz_recenice; ++j)
{
cout << "test2, ";
if (recenica[i] == recenica[j])
{
cout << "test3, ";
++br_ponavljanja;
recenica.erase(recenica.begin() + j);
}
cout << "test4, ";
}
cout << recenica[i] << ": " << br_ponavljanja << endl;
}
cout << "test5, ";
getchar();
return 0;
}
What's the problem with the std::cout?
Add << flush to flush your output buffer (each place).
Or use << endl, which both adds newline and flushes.
There are problems with the code, especially for empty input, but that's what you're out to learn about, so I'll leave you to it! :-)
Cheers & hth.,
I'm afraid the language eludes me in terms of variable names, but this "Works for Me™".
Here is my output (First 3 lines input:)
ytreyert
tyryteter
gdhdfgdf
^Z
test0, test, !test2, test4, test2, test4, ytreyert: 1
test, !test2, test4, tyryteter: 1
test5,
You should definitely try flushing the cout buffers after printing (as per Alf's answer).
I notice that gdhdfgdf is not counted, this is because of this line:
for (int i = 0; i < duz_recenice - 1; ++i)
If you only give 1 input word, this loop will not run, as you do duz_recenice = recenica.size(); before looping.
Changing this line to
for (int i = 0; i < duz_recenice; ++i)
solves this problem.