simple c++ input function - c++

i am new to c++ from other languages, and looking at examples this code looked like it should work
#include <iostream>
using namespace std;
main()
{
string input = "";
cout << "in: ";
getline(cin, input);
input_recv(input);
}
input_recv(input)
{
if (input == "hello"){
cout << "derp" << endl;
}
}
it will not let me use the function input_recv. it gives me several errors in my IDE. one being `input_recv' undeclared (first use this function). basically what i am trying to do for this is make it respond to input using a function.
EDIT:
#include <iostream>
#include <string>
using namespace std;
void input_recv(string);
int main()
{
while (1 == 1){
string input = "";
cout << "in: ";
getline(cin, input);
input_recv(input);
cin.get();
}
}
void input_recv(string input){
if (input == "hello"){
cout << "derp" << endl;
}
}
thanks

C++ requires the function to be declared before it's used, so if you move the input_recv definition above the main function, it will work. Otherwise, you can leave the program the way it is and add a forward declaration above main like this:
void input_recv(string);
int main()
{
...
}
void input_recv(string input)
{
...
}
Edit:
There are a few other errors here as well as other comments pointed out. One, functions should have a return type and parameter types specified. Also, before using the string type, you need to
#include <string>.

Declare the function first, and use a correct function prototype, here there is not type for input, no return type ... Example below,
#include <iostream>
#include <string>
void input_recv(const std::string& input);
int main()
{
std::string input = "";
std::cout << "in: ";
std::getline(std::cin, input);
input_recv(input);
return 0;
}
void input_recv(const std::string& input)
{
if (input == "hello"){
cout << "derp" << endl;
}
}

C++ is a strongly-typed language. You must declare your variables and your functions with explicit types:
// forward declare your function
void input_recv(std::string input);
// alternatively
void input_recv_better(const std::string& input);
int main()
{
std::string input;
std::cout << "In: ";
std::getline(std::cin, input);
input_recv(input);
input_recv_better(input);
return 0;
}
void input_recv(std::string input)
{
if (input == "hello")
{
std::cout << "derp" << std::endl;
}
}
void input_recv_better(const std::string& input)
{
if (input == "hello")
{
std::cout << "derp!" << std::endl;
}
}

There's a few things definitely wrong with this snippet, I will correct them all so you can observe the difference:
#include <iostream>
using namespace std;
void input_recv(string input);
int main()
{
string input = "";
cout << "in: ";
getline(cin, input);
input_recv(input);
}
void input_recv(string input)
{
if (input == "hello"){
cout << "derp" << endl;
}
}
I have added return types to your functions, data types to your parameters, and a forward declaration of the input_recv function so that the main function knows it exists.
You will definitely want to pick up a book like C++ Primer (the latest edition revised for the C++11 standard) before learning bad practice by trying to forgo some sort of standard training.

#include <iostream>
using namespace std;
void input_recv(string input)
{
if (input == "hello"){
cout << "derp" << endl;
}
}
int main()
{
string input = "";
cout << "in: ";
getline(cin, input);
input_recv(input);
return 0;
}

Related

Having trouble with std::string::compare() return values in c++

Relatively new to c++.
Having trouble understanding an issue I am having with the compare() function returning 1 instead of 0.
I have a program which reads a text file containing an arbitrary number of questions and answers for a quiz. It is formatted as such:
Q: How many days in a week?
A: seven
I have three files, main.cpp, Quiz.cpp, and Quiz.h:
main.cpp:
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include "Quiz.h"
using namespace std;
int main(int argc, char* argv[]){
srand(unsigned(time(0)));
vector<Quiz> quizVector;
ifstream inputQuiz;
inputQuiz.open(argv[1]);
string q, a;
int questionCount = 0;
if(inputQuiz.is_open()){
getline(inputQuiz, q);
getline(inputQuiz, a);
while(!inputQuiz.eof()){
Quiz *instance = new Quiz(q, a);
quizVector.push_back(*instance);
questionCount++;
getline(inputQuiz, q);
getline(inputQuiz, a);
}
}
random_shuffle(quizVector.begin(), quizVector.end());
string userInput;
for(int i = 0; i < questionCount; i++){
cout << quizVector[i].getQuestion() << endl;
cout << "A: ";
getline(cin, userInput);
if(quizVector[i].getAnswer().compare("A: " + userInput) == 0){
cout << "Correct." << endl;
}
else{
cout << "Incorrect." << endl;
}
}
return 0;
}
Quiz.cpp:
#include <string>
#include "Quiz.h"
int Quiz::score = 0;
std::string Quiz::getQuestion(){
return question;
}
std::string Quiz::getAnswer(){
return answer;
}
Quiz.h:
#ifndef QUIZ_H
#define QUIZ_H
class Quiz{
private:
std::string question {""};
std::string answer {""};
public:
Quiz() = default;
Quiz(std::string q, std::string a) : question {q}, answer {a} {}
std::string getQuestion();
std::string getAnswer();
};
#endif
My problem lies within main.cpp:
for(int i = 0; i < questionCount; i++){
cout << quizVector[i].getQuestion() << endl;
cout << "A: ";
getline(cin, userInput);
if(quizVector[i].getAnswer().compare("A: " + userInput) == 0){
cout << "Correct." << endl;
}
else{
cout << "Incorrect." << endl;
}
}
When I input the correct answer corresponding to each question, compare() does not return 0, but consistently returns 1. There are no leading or trailing spaces at the start or ends of each line in the text file. Am I misunderstanding how getline() or compare() works? Is it something else? Any help is appreciated!
I see a number of problems with this code:
std::random_shuffle() is deprecated in C++14 and removed in C++17, use std::shuffle() instead.
you are not validating that argv contains an input parameter before using it.
Your use of eof() in the while loop is wrong. For instance, if the last question/answer pair in the file is terminated by EOF instead of a line break, getline() will still return the question/answer to you, but it will also set the eofbit flag on the stream, which will cause eof() to return true and thus you will skip saving the last pair into the vector. The stream is not technically in a failed state yet in this situation (see the diagram at https://en.cppreference.com/w/cpp/io/basic_ios/eof), so you shouldn't skip the last pair if it terminates with EOF rather than a line break.
Your while loop is leaking memory.
you don't need questionCount at all, use quizVector.size() instead. Or better, a range-for loop.
you don't really need to use compare() at all, you can use operator== instead. But, if you do use compare(), you should take into account that it is case-sensitive (as is operator==). You should also take advantage of the fact that compare() lets you specify an index to start comparing from, so you can ignore the A: prefix in the stored answer (alternatively, you could just strip off the Q: and A: prefixes when storing the question/answer in Quiz's constructor). Otherwise, you can use your compiler's strcmpi() function instead (if it offers one).
Try something more like this instead:
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
#include <random>
#include <cctype>
#include "Quiz.h"
using namespace std;
string toLowercase(string s) {
transform(s.begin(), s.end(), s.begin(),
[](unsigned char c){ return tolower(c); }
);
return s;
}
int main(int argc, char* argv[]){
if (argc < 2){
cerr << "Please specify a file to open!" << endl;
return 0;
}
ifstream inputQuiz(argv[1]);
if (!inputQuiz.is_open()) {
cerr << "Can't open the file!" << endl;
return 0;
}
vector<Quiz> quizVector;
string q, a, userInput;
while (getline(inputQuiz, q) && getline(inputQuiz, a)) {
quizVector.emplace_back(q, a);
}
random_device rd;
mt19937 g(rd());
shuffle(quizVector.begin(), quizVector.end(), g);
for(auto &quiz : quizVector){
cout << quiz.getQuestion() << endl;
cout << "A: ";
getline(cin, userInput);
userInput = toLowercase(userInput);
a = toLowercase(quiz.getAnswer());
if (a == ("a: " + userInput)) {
// or:
// if (a.compare(2, string::npos, userInput) == 0) {
// or, if you strip off "A:" beforehand:
// if (a == userInput) {
cout << "Correct." << endl;
}
else {
cout << "Incorrect." << endl;
}
}
return 0;
}

Passing a string vector to a function and function prototype issue c++

In this example, the compiler says the function "list" doesn't have a definition, despite me writing one below. If I move the function definition to the top so there is no prototype, it compiles fine.
Can someone explain what's happening here?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void stuff();
void list(vector<string> things);
bool alive = true;
int main()
{
vector<string> things;
things.push_back("Lots");
things.push_back("Of");
things.push_back("Things");
do
{
cout << "What do you want to do?\n\n" << endl;
string input;
cin >> input;
if (input == "stuff")
{
stuff();
}
if (input == "list")
{
list();
}
} while (alive);
return 0;
}
void list()
{
cout << "The things are:\n\n";
for (int i = 0; i < things.size(); ++i)
{
cout << things[i] << endl;
}
}
void stuff()
{
cout << "Some stuff" << endl;
}
Your list function definition signature differs from your function declaration. The function signature should be the same. Your function definition signature should also accept one parameter:
void list(std::vector<string> things)
{
std::cout << "The things are:\n\n";
for (int i = 0; i < things.size(); ++i)
{
std::cout << things[i] << '\n';
}
}
And in your program you call the function with:
list();
where it should be:
list(things);
void list(vector<string> things); is not the same as void list(). You need to actually define your function as void list(vector<string> things) not just the prototype.

My while loops seems to be ignoring my getline

Here's all the code
#include <iostream>
#include <string>
#include <windows.h>
#include <stdlib.h>
using namespace std;
void Pdelay(string str)
{
for (char c : str)
{
std::cout << "" << c << "";
Sleep(100);
}
std::cout << '\n';
}
int main()
{
int exit = 1;
while (exit == 1)
{
cout<< "Type something\n:";
string str;
str.clear();
getline(cin,str);
Pdelay(str);
cout << "\n\n[1]Type something again"<< endl;
cout << "[2]Exit\n:";
cin >> exit;
}
return 0;
}
Whenever I run it, it works properly the first time round, when it loops back it skips the getline and continues with the two cout statements.
Immediately after you use cin, the newline remains in the buffer and is being "eaten" by the subsequent getline. You need to clear the buffer of that additional newline:
// immediately after cin (need to #include <limits>)
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
That's why it's not a very good idea to combine std::cin and std::getline. BTW, you can write your code in fully standard compliant C++11, with no additional non-library headers:
#include <chrono>
#include <iostream>
#include <limits>
#include <string>
#include <thread>
void Pdelay(std::string str)
{
for (char c : str)
{
std::cout << "" << c << "" << std::flush;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
std::cout << '\n';
}
int main()
{
int ext = 1;
while (ext == 1)
{
std::cout << "Type something\n:";
std::string str;
str.clear();
std::getline(std::cin, str);
Pdelay(str);
std::cout << "\n\n[1]Type something again" << std::endl;
std::cout << "[2]Exit\n:";
std::cin >> ext;
if(!std::cin) // extraction failed
{
std::cin.clear(); // clear the stream
ext = 1;
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
}
I just realized that this question has been asked (in a slightly modified form) before, and the answers are great:
Why does std::getline() skip input after a formatted extraction?

Function must return a value

I am trying to make a text based RPG and i'm fairly new to c++. I understand that I need to return a value, but when I try and return CharacterName or CharacterRace it comes up with unresolved externals errors. I'd really appreciate the help guys, thanks :)
CharacterCreation.h
#include <string>
#include <iostream>
void petc(), ConsoleClear(), petc(), EnterClear();
std::string CharacterName, CharacterRace;
Main.cpp
#include <iostream>
#include <limits>
#include <string>
#include <string.h>
#include "CharacterCreation.h"
std::string CharacterCreation();
int main()
{
CharacterCreation();
}
std::string CharacterCreation(int RaceChoice, int RaceChoiceLoop)
{
RaceChoiceLoop = 0;
std::cout << "Welcome to the character creation V 1.0.0" << std::endl;
EnterClear();
std::cout << "Choose a name: ";
std::cin >> CharacterName;
std::cout << CharacterName << std::endl;
EnterClear();
while (RaceChoiceLoop == 0)
{
std::cout << "(1) Human - Human's race perks: + 5 to Magic | + 1 to Sword Skill" << std::endl;
std::cout << "(2) Elf - Elve's race perks: + 5 to Archery | + 1 to Magic" << std::endl;
std::cout << "(3) Dwarf - Dwarven race perks: + 5 to Strength | + 1 to Archery" << std::endl;
std::cout << "Choose a race, " << CharacterName << ": ";
std::cin >> RaceChoice;
if (RaceChoice == 1)
{
RaceChoiceLoop = 1;
CharacterRace = "Human";
}
else if (RaceChoice == 2)
{
RaceChoiceLoop = 1;
CharacterRace = "Elf";
}
else if (RaceChoice == 3)
{
RaceChoiceLoop = 1;
CharacterRace = "Dwarf";
}
else
{
std::cout << "Invalid Option";
EnterClear();
RaceChoiceLoop = 0;
}
}
}
void petc()
{
std::cout << "Press Enter To Continue...";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
void EnterClear()
{
std::cout << "Press Enter To Continue...";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
system("cls");
}
void ConsoleClear()
{
system("cls");
}
A declared std::string function should return a string and this is not the same as printing it on the screen, use return "something" inside the function otherwise declare it void.
The "unresolved externals" message isn't directly caused by your returning a value.
It's a linker error, and only occurs because compilation succeeded.
The cause is that you're declaring, and calling, this parameter-less function:
std::string CharacterCreation();
but you're defining this function with two parameters:
std::string CharacterCreation(int RaceChoice, int RaceChoiceLoop)
The declaration and the definition must match.
From the looks of it, you don't actually want the parameters and should use local variables instead:
std::string CharacterCreation()
{
int RaceChoice = 0;
int RaceChoiceLoop = 0;
// ...
Problem is that the function CharacterCreation() (taking no arguments) is never defined, and thus the linker cannot find it.
Try substituting in the following:
std::string CharacterCreation(int, int);
int main()
{
CharacterCreation(1,1);
}
This will call the CharacterCreation function you have implemented below the main function. Doing this I can compile (and link) your code :)
As I have pointed in my comment before, your CharacterCreation method does not return any value, although you have defined a string as an expected one.
What you most likely want to do is either change CharacterCreation signature to:
void CharacterCreation(int RaceChoice, int RaceChoiceLoop)
and keep the current implementation
or pack all your console output in a string and return it at the end of the method.
Then in main()
string result = CharacterCreation();
can retrieve this value and you can print it in main

In C++, how do I ask the user to input a string, have that string stored, and be able to recall it in any/many functions?

I want to be able to have the user enter their name, store it and be able to recall it in different functions. This is my first code, first program. I am sure there is an easier way to do this, so if you could offer both an answer to the question and a easier way of accomplishing this task it would be much appreciated. Thank you in advance.
This is what I have so far:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
using namespace std;
void game();
void other();
class NameClass{
public:
string name;
};
int main()
{
int a;
int age;
string name;
cout << "Hello user, what is you name? \n\n";
/*Not sure if class and operator needs to be here. I was hoping that when the user
input the stream(their name) it would be stored in the class as well as being able
to use it in the main function.*/
NameClass person;
//This line is here to get name from user.
getline(cin, name);
cout << "Well " << name << ", are you having a good day? \n\n";
cout << "1=Yes 2=No \n\n";
cin >> a;
cout <<"\n";
if(a==1){
cout << "Well that is good to hear.\n\n";
}else{
cout << "I am sorry to hear that. I hope things get better for you. \n\n";
}
cout << "Do you want to play a game? \n\n";
cin >> a;
if(a==1){
game();
}else{
other();
return 0;
}
return 0;
}
void game(){
/*It is in this function that I want the be able to recall the name that the user input in the main function.*/
cout << "Cool "<< name <<",let get started." << endl;
}
void other(){
cout << "Well then "<< name <<", lets do something else.";
}
I assume you aren't aware of the OOP concepts.
Do this (make methods part of the class):
class NameClass{
public:
string name;
void game();
void other();
};
int main()
{
...
NameClass person;
getline(cin, person.name);
...
}
Or this (pass name as parameter):
int main()
{
string name;
...
game(name);
}
void game(string name)
{
cout << "Cool "<< name <<",let get started." << endl;
}
If you want to pass information from one function to another then you use a function parameter (or more than one).
void game(string name);
int main()
{
string name;
...
game(name);
}
void game(string name)
{
cout << "Cool "<< name <<",let get started." << endl;
}
It's a fundamental concept that pretty much all programming languages have.
Just pass the name as a parameter in both your functions, it should be something like this:
//functions
void game(string name);
void other(string name);
In your main function when you call either function just pass the name to it.
if(a == 1)
{
game(name);
}
else
{
other(name);
}