'strToDouble' was not declared in this scope Lab1-3.cpp /Lab1-3/src line 65 C/C++ Problem
The first problem, as #SoronelHaetir pointed out, is that you were trying to assign title to variable which can only hold one character. Instead, you should use char array, char pointer, or even string object to contain your multi-letter value. In my code example below, I used char array with fixed size of 25, to store the title. Beware that you can store only up to 24 characters in it, because char arrays need special character which will denote the end of char array. Otherwise it would end up writing junk after your desired value. That special character is null-terminating character which is written like '\0'.
Using return; statement in your void displayBid(Info itemOne); function was completely unnecesary. While you can use return; to stop function from executing, you placed it at the end of function which was just about to end itself in normal way, but you forced it with no reason. Besides, you do not need any return; statements for functions which return void – nothing.
Then, fund and bidAmount are representing money value, which may or may not be of integer value, so you should consider float or double data types to store money value.
Next thing is your function Info getBid();. First, I have to say that naming may be a bit confusing. If you read the name of that function without seeing its actual code, how would you understand what it may do? For me, it sounded like it is about to get me information about a bid, while actually it is setting it up. Second, you could simplify code for entering values, in the way I did it in my code example. The way you tried to use different techniques for getting values from user input was a bit wrong. getline is member function which is used with istream objects. Your istream object is cin. In order to access that member function you shall write it as cin.getline(to be discussed);. That function only works with characters. Its first parameter accepts pointer to the first character (address of the first character) in sequence of characters.
Second parameter is of integer data type and specifies how much characters you want to be extracted from your input and stored in an argument which is in place of the first parameter. Beware not to write, for example, 25, because in char array you have to leave one place for '\0' character, which is automatically placed where it needs to be. getline member function has also default delimiter '\n', which denotes new line. It means that you can enter less characters than function can extract, because extraction will stop as soon as it reads that delimiter value from user input. Although, if you want your specific delimiter, getline member function has its overloaded version which third parameter is one where you enter desired delimiter as an argument. (Overloaded functions are basically functions with the same name, but different parameters. They provide same functionality with different implementation.)
Even if you had set up values for a bid, you never returned it from function. You correctly said that its return value is Info, but you did not return it. Actually, you again exited just before its normal exit. Instead, you should have written return itemOne; In my code example, I passed the variable created in int main(); function by reference, which means it is not a copy as usually, so I do not have to return it and assign to another variable of the same type to appropriately apply desired changes.
Finally, in the int main(); function, you could just declare int choice, without initializing it and use do-while loop in the way I did it. Also, switch statement provides defining what will happen if none of the cases are true, in the way that after all cases you write default:, and below it whatever you want to happen. In your code example, your function will continue executing even if user enters anything but 1, 2 except for 9 defined to stop its execution. In my code example, whatever user enters besides 1 and 2, including zero, function will exit. Well, except for new line.
And, let us discuss again the naming. Your data structure name has to directly imply what it is. Info does not do that. That name would actually be more appropriate for your void displayBid(Info itemOne); function to be called. In my code example, I renamed it to Bid.
#include <iostream>
using namespace std;
struct Bid
{
char title[25];
int vehicleID;
double fund;
double bidAmount;
};
void GetBid(Bid item)
{
cout << "Title: " << item.title << endl;
cout << "Fund: " << item.fund << endl;
cout << "Vehicle: " << item.vehicleID << endl;
cout << "Bid Amount: " << item.bidAmount << endl;
}
void SetBid(Bid & item)
{
cout << "Enter title: ";
cin >> item.title;
cout << "Enter fund: ";
cin >> item.fund;
cout << "Enter vehicle ID: ";
cin >> item.vehicleID;
cout << "Enter amount: ";
cin >> item.bidAmount;
}
int main()
{
Bid item;
int choice;
do {
cout << "Menu:" << endl;
cout << " 1. Enter Bid" << endl;
cout << " 2. Display Bid" << endl;
cout << " 0. Exit" << endl;
cout << "Enter choice: ";
cin >> choice;
switch (choice)
{
case 1:
SetBid(item);
break;
case 2:
GetBid(item);
break;
default:
choice = 0;
cout << "Goodbye." << endl;
break;
}
} while (choice != 0);
return 0;
}
The first (and biggest) problem is:
char title;
This allows you to store only a single character rather than an entire name (prefer std::string to char arrays).
Related
This is a simplified and more informative version of a question that has now been deleted.
BACKGROUND
I am currently trying to familiarize myself with basic C++ programming and decided to make a game of hangman. However, I noticed that an integer variable called preset_count—which is meant to count how many letters have been pre-guessed by the game— always returns a value of 0 in the main() function whereas in other functions, it has a value of 2 (or anything greater than 0).
What I am trying to accomplish here is that the program will automatically fill in the vowels of the word the player is trying to guess. Depending on how many vowels are filled in, the score the player gets when guessing a character right increases.
For example, the player is trying to guess the word "eraser," so the hangman program will print out
"e _ a _ e _ " they will gain 334 points if they guess correctly.
In a word like "circle," though (which will be printed as "_ i _ _ _ e ") the player will gain 250 points per guess because of the fact that the player has to guess 4 characters instead of 3.
THE ISSUE AND CODE
In order to accomplish this, I added code meant to count how many vowels have been filled in by the game in a special function.
The code below is a simplified version of the one in the actual hangman program that re-creates the issue I have with the program. See, the game outputs a different value of the preset_count value in each function.
Essentially, the main() function has a
cout << "preset_count in main(): " << preset_count;
//This line of code prints out 0. However, the variant of this in find_preset():
cout << "preset_count in find_preset(): " << preset_count;
//Which, on the other hand, prints out 3.
Is there any reason behind these contradictory variable reports? Is there any way to solve this?
#include <iostream>
using namespace std;
void find_preset (int, const string, string); //Prototyping for find_preset()
int main() {
int preset_count = 0; //Amount of times a character in PRESET_LETTERS appears in the word variable.
const string PRESET_LETTERS = "AEIOUaeiou"; //The letters the program is looking out for.
string word = "eraser"; //The word being analyzed.
cout << "\nmain(): main() executed, variables declared, about to execute find_preset() function.";
find_preset(preset_count, PRESET_LETTERS, word); //find_preset() function; finds how many PRESET_LETTERS characters are in word.
cout << "\nmain(): find_preset() finished executing.\n"; //Announces that find_preset() function finished executing.
cout << "\n\nDEBUG word: " << word << endl; //Report on the set word value.
cout << "DEBUG preset_count in main(): " << preset_count << endl << endl; //Report on preset_count's value in main().
//This is where my issue takes place in. This reports a value whereas in find_preset(), the value of preset_count is 2.
return 0;
}
//find_preset() function; finds how many PRESET_LETTERS characters are in word.
void find_preset(int preset_count, const string PRESET_LETTERS, string word) {
int word_index = 0; //How many characters of word that find_preset() has gone through.
cout << "\nfind_preset() executed, now counting amount of instances of PRESET_LETTERS in word.";
//While word_index is less than the size of word. While the entire word variables hasn't been scanned yet.
while (word_index < word.size()) {
//If a PRESET_LETTERS character is found in word.
if(word.find(PRESET_LETTERS)) {
preset_count++; //preset_count increased by 1.
cout << "\nfind_preset(): preset_index and preset_count increased by 1."; //Reports preset_count++; has been executed.
}
word_index++; //Word index increased by 1.
cout << "\nfind_preset(): word_index increased by 1."; //Reports that word_index++; has been executed.
}
cout << "\nfind_preset(): while (word_index < word.size()) finished executing, now printing debug menu for find_preset().\n";
//Reports that the while loop has finished executing.
cout << "\n\nDEBUG: preset_count in find_preset(): " << preset_count; //Report on preset_count's value in find_preset().
//This is also where my issue takes place in. This reports that preset_count's value is 2 whereas in main, it reports 0.
cout << "\nDEBUG: word_index value: " << word_index << endl << endl; //Report on word_index's value.
}
The arguments in C++ are copies of what are passed by default. Therefore, modifications of arguments in callee functions won't affect what are passed in caller. You should add & to make the arguments to references if you want to have functions modify what are passed.
Both declaration and definition should be modified.
void find_preset (int&, const string, string); //Prototyping for find_preset()
void find_preset (int& preset_count, const string PRESET_LETTERS, string word) //find_preset() function; finds how many PRESET_LETTERS characters are in word.
{
int position = 0;
void set_position() {
std::cout << "Player " << player << "'s Turn (Enter 1-9): ";
while (!(std::cin >> position)) {
std::cout << "Player " << player << ", please enter a valid number between 1 and 9: ";
std::cin.clear();
std::cin.ignore();
}
std::cout << "\n";
while (board[position-1] != " ") {
std::cout << "Oops, there's already something in that position!\n\n";
std::cout << "Player " << player << "'s Turn (Enter 1-9): ";
std::cin >> position;
std::cout << "\n";
}
}
This is a solution to a tic tac toe challenge in Codecademy and I would like to understand if the function while (!std::cin >> position)) actually checks if it is 1 to 9. Position is just an int, declared as int position = 0;. How does this actually check if it's 1 through 9? Or does it just check if it's an integer? So far Codecademy's C++ course seems to be pretty bad and doesn't go through that much.
Too Long Didn't Read (TLDR)
That code only filters out non-numbers.
Explanation:
To help you understand, lets look at what actually happens inside
while(!(std::cin >> position))
On the inside of all that lies std::cin >> position. >> is the "extraction operator", so we're going to extract something from std::cin (standard input). Using the >> operator really just turns around and calls operator>>() on the given object. The given object in this case is a std::istream. It's operator>>() call signature looks like:
istream& operator>> (int& val)
It returns an istream (itself), and takes a reference to an int, position in your case.
So if we evaluate std::cin >> position mentally (or in a debugger, which is much better: zero guesswork), we'll see that we've returned that istream (which is almost certainly a return *this; at the end of the function).
Now lets replace std::cin >> position with the effective return value std::cin and see what the code looks like.
while(!(std::cin))
Okay, so we need to apply the ! operator to the istream named cin. "Wait what?!" you cry... Any class/struct can define a variety of different operators, such as <<, >>, =, ==, >, <, !, *, ->... there's a bunch of them. The relevant one is the ! operator, with the following function signature and documentation:
bool operator!() const
Returns true if either failbit or badbit is set, and false otherwise. This is equivalent to calling member fail.
Incidentally, the const on the end means "we promise not to change the object running the function". This allows the compiler to make various optimizations, knowing the object's state won't change. It also lets our fellow programmers know what sorts of things are happening (and not happening) inside the function.
We'd expect that this would return true (fail or bad was set) when you type a non-digit into operator>>(int&), and we'd be right. Cheers to the library designers for following the "Principle of Least Surprise".
The return of value of operator!() is then passed into the while loop. So if someone types a letter or punctuation or what have you, they'll see the error message and have to type again.
Conclusion:
This doesn't do anything for filtering out numbers outside of 1-9, it just filters out non-numbers. You'd need new code for that, such as the suggestion in the comment by #Eljay.
So I'm having some trouble with my program. It doesn't seem to fill the array properly. It dosen't seem to populate pass element 0, even though I'm increasing i. When I debug and go back, i remains zero. Should I be doing something different? I feel like I'm passing or updating the array improperly. Can't really use any STL libraries. Thank you in advance for any help.
struct Client
{
string name;
string zip;
double balance;
};
Client bAccounts [30]; //structural array in main()
int addClnt(Client(&bAccounts)[30], int); //prototype
int addClnt(Client(&bAccounts)[30], int clientCount) //function to add
elements
{
cout << "Enter Account Name:" << endl;
cin >> bAccounts[i].name;
cout << "Enter Account Zip:" << endl;
cin >> bAccounts[i].zip;
cout << "Enter Account Balance:" << endl;
cin >> bAccounts[i].balance;
cout << "Enter Last Transaction" << endl;
cin >> bAccounts[i].lastTrans;
clientCount++; //to return number of clients added
i++; //to populate different element of array on next call of function.
return clientCount + 1;
}
So I added + 1 to return clientCount and then set i = clientCount. However, clientCount remains at zero and dosen't update.
The reason the array doesn't have any values after the first one is because you never reach passed the first element. You increment i at the end of the function, but at the top of your addClnt function, i is set back to 0 . This will just keep resulting on overwriting the old previous data
EDIT:
#include <iostream>
//use pass by reference (&)
void add_client(int& index_loc){
//do whatever
//this changes the actual value passed into the function
index_loc++;
}
int main(){
int loc = 0;
add_client(loc);
add_client(loc);
add_client(loc);
//outputs 3
std::cout << "current #: " << loc << "\n";
}
clientCount is only getting incremented in that functions scope. When that function goes to it's return statement, all variables and all the work it did has completely died.
You are passing clientCount by value and not by reference, so clientCount will always be 0, and incrementing it inside that local function won't actually change clientCount's value outside of the function.
What you need to do is pass it by reference.
EDIT: The chosen answer does not explain why his solution works. The answer provided is incorrect.
The reason why the code works because again, you pass by reference and not by value.
As a c++ beginner I've written the following code:
int main(void){
struct car{
char * make[200];
int manfYear;
};
int num=0;
cout << "How many cars do you wish to catalogue? ";
cin >> num;
car * Cars = new car [num];
for (int i=1;i<=num;i++){
cout << "Car #" << i << ":" << endl << "Please enter the make: ";
cin.getline(*Cars->make,200);
cout << "Please enter the year made: ";
cin >> Cars->manfYear;
}
My problem is that I can't get my head round a problem where I get a segfault when running the program at the point I need to enter the model of the car. Can someone please explain what I'm doing wrong?
As far as I understand it I'm passing a pointer to the array "make" which should make it work. Is my understanding way off?
Thanks in advance
Dan
Four issues I see right away:
Issue 1
In your struct, you have:
char * make[200];
In English, this is saying, "create an array of 200 pointers to character", when I think you want to say, "create an array of 200 characters." So you should have instead:
char make[200].
Issue 2
You are looping by starting at 1. This will skip the first car in the array - remember arrays are zero-indexed. So you should have instead:
for (int i = 0 ; i < num ; i++)
and for display purposes, you could say:
cout << "Car #" << (i+1) << ":" << endl << "Please enter the make: ";
Issue 3
Where you say:
cin.getline(*Cars->make,200);
and
cin >> Cars->manfYear;
Where in these lines are you specifying which car the user is populating? Nowhere. If you are looping with i, then you need to actually mention i. These should work:
cin.getline(Cars[i].make,200);
and
cin >> Cars[i].manfYear;
Notice that we are using ., not ->. This is because the items in the Cars array are actual instances, not pointers. The Cars array is itself a pointer, but not its contents.
Issue 4
All credit to #Ben C who pointed this out first: mixing the >> operator with getline() function on cin can lead to strange behavior, with leftover CR's from >> going into the getline() call. You could use either all >> (disadvantage: you don't have the 200 limit enforced when reading the make) or all cin.getline() (disadvantage: you will have to use string buffers and then convert them for number of cars and year), or put cin.ignore() after each invocation of >>, like so:
cin >> num;
cin.ignore();
and
cin >> Cars[i].manfYear;
cin.ignore();
Again, all credit to #Ben C for noticing this first.
Last But Not Least
By convention, classes/structs have capital names, and variables have lowercase / camelcase names. Consider renaming the struct from car to Car, and the array from Cars to cars. In other words, the reverse of the capitalization you have right now.
Finally, I concur with all the other posters here: you should consider using string instead of char arrays.
First, use string instead of poor old C char[].
Next: you don't want char * make[200];. You want char make[200];. char * make[200] is an array of 200 pointers to chars, which can be used as 200 null-terminated strings - but then, you would have to new[] each of them. Just use char make[200]; and cin.getline(Cars->make, 200);.
char * make[200] declares an array of 200 pointers; I'm guessing this isn't what you're after.
If you're simply looking to store a string, I'd recommend taking a look at the C++ string type instead.
#include <iostream>
#include <string>
int main()
{
using namespace std;
struct car
{
string make;
int manfYear;
};
int num=0;
cout << "How many cars do you wish to catalogue? ";
cin >> num;
car * Cars = new car [num];
for (int i=1;i<=num;i++)
{
cout << "Car #" << i << ":" << endl << "Please enter the make: ";
std::cin.ignore();
getline(cin, Cars[i-1].make);
cout << "Please enter the year made: ";
cin >> Cars[i-1].manfYear;
}
}
There were also a couple of other minor niggles with your code.
1) You had been using Cars->manfYear - this will only ever point you to the first element of your array. I'm assuming you don't want that; using the subscripting syntax as per Cars[i-1].manfYear will access an individual car object in your array. (Remember that array indexes start from zero! - it would actually make more idiomatic sense for your for loop variable to start at zero as well really)
2) Be wary of the way std::getline and the >> symbol work together. the >> (stream extraction operator) often leaves any newline characters, which means you might see "odd" behaviour with your calls to getline. If you're mixing the two together, then using something like std::cin.ignore() will help you discard the newline character.
First of all, arrays in C++ are indexed from 0..n-1, so your loop needs to run from
for (int i = 0; i < num; i++) { ... }
Secondly, you've declared make as a 200-element array of pointer to char; this is most likely not what you want. If make is supposed to store a character string, declare it as a plain array of char:
struct car{
char make[200];
int manfYear;
};
Finally, rewrite your getline call as
cin.getline(Cars[i].make, sizeof Cars[i].make); // fixed per comment below
Even though Cars is declared as a pointer, you can use the subscript operator on it as though it were an array; by doing so, you implicitly dereference Cars, since a[i] is interpreted as *(a + i). This also means that you will use the . component selection operator as opposed to the -> operator, since the type of Cars[i] is car, not car *.
First of all char *make[200] is not a string of max 200 characters but 200 pointers to char.
Second thing: you are dereferencing the pointer in cin.getline with *: what happens is that you obtain the value contained in first cell of the 200 char* pointers. But you didn't initialize the single pointers, just the higher level one, so you get a segfault.
Just change char* make[200] to char make[200] and *Cars->make to Cars[i].make.
I use Visual C++ 2010 Express Edition to compile and run the .exe files I write in the C++ programming language. I am trying to create a loop-based logic using C++ to ask the user how many entries he chooses to enter, and ask questions limited to that no. of entries. For example I want to output, "How many characters do you wish to enter?: " Say the user gives the answer as '3' which is stored in the int variable 'entries'. I then want to keep asking the question 3 times before it stops and continues with the next line of code. I hope you understand, here is a block of code to demonstrate what I am doing:
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "How many values do you need to enter?: ";
int entries;
cin >> entries;
int offset, number;
string valueName[50];
float valueValue[50];
for (offset = 0; offset < entries; offset++)
{
cout << "Enter " << number << " Value Name: ";
cin >> valueName[offset];
cout << "Enter " << valueName[offset] << "\'s value: ";
cin >> valueValue[offset];
for (number = 1; number <= entries; number++)
{
}
}
char response;
cin >> response;
return 0;
}
Strangely when I run this simple program, it fails when I enter the value's name to be inserted into the 0th element of the valueName[] array. It just pauses the execution of the program and a dialog box pops up saying "Runtime Check Failure #3 - Variable 'number' is being used without being initialized!" Another problem regarding this program is that, for quite some time, when I ran this program this "Runtime Check Failure #3" box never appeared, and when it didn't, the number value went wrong, and first started with 1, and then for the next loop jumped to 6, and then repeated 6 again for the next loop! Please help me! I've checked online scouring this problem everywhere, but it just doesn't apply to my type of problem! Is it because the variables are out of scope? But they're declared outside the for loops right? So please help me!
The runtime is telling you the truth, the following line comes after you have declared number as an int but have not given it a value.
cout << "Enter " << number << " Value Name: ";
In your code you declare the following, in C++ this means give me 2 ints but the values are not defined yet, e.g.
int offset, number;
Change it to something like this ..
int offset = 0;
int number = 0;
You are printing the variable number without assigning to it first, i.e. it's uninitialized. When it prints some random number it's because that what happens to be in the memory at the time you run the program. Assign a value to it before you use it.
The problem is exactly the error message you're getting. You're using the variable number without initializing it.
You use the variable right here, at the top of your loop, when it hasn't been initialized to anything yet:
cout << "Enter " << number << " Value Name: ";
What is your intention with the number variable? It doesn't really seem to be serving any purpose. If you want to print which entry you're currently on, you could use the offset variable instead, like this:
cout << "Enter " << offset << " Value Name: ";
But that still seems a little unclear to me.
But the reason that you're having a problem is because the value is uninitialized, so you're experiencing undefined behavior. This is also the reason that Visual Studio doesn't always catch it; it will probably always catch in Debug mode, but in Release mode it will almost never catch it. You need to initialize all your variables before you use them.
In my case it was because an extern variable was declared twice.