I'm trying to learn C++ and I'm creating small little programs to test out how it works. I made this code but for some reason I get this error on compiling:
binary '>>': no operator found which takes a left-hand operand of type 'std::istream' (or there is no acceptable conversion)
If anyone could help me figure this out I would appreciate it.
Code:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <string>
#include "logo.h"
class classTest
{
public:
void setName(std::string x)
{
name = x;
}
std::string getName()
{
return name;
}
private:
std::string name;
};
int main()
{
SetConsoleTitle("plains.exe");
displayLogo();
std::cout << "Please enter your name: ";
classTest testObject;
std::cin >> testObject.setName;
std::cout << "Your name is " << testObject.getName() << "." << std::endl;
return 0;
}
setName is a function. So, you can not use cin >> testObject.setName. You can either do this-
string name;
cin >> name;
testObject.setName(name);
or use Operator Overloading to overload >>.
You are calling the instream operator on a void function
std::cin >> testObject.setName;
You need to first take the input in a string like and then call the setter to set the value
string inputName;
std::cin>>inputName;
testObject.setName(inputName);
Related
So what i am trying to do is basically get the second argument of a function, and making the second argument the name of a variable so i can easily store the users input. Here is my code
`
#pragma once
#include <iostream>
using namespace std;
void askAndStore(string question, string variable)
{
cout << question + " ";
cin >> variable;
}
`
Pass variable by reference:
void askAndStore(string question, string& variable)
{
cout << question + " ";
cin >> variable;
}
string& instead of string. Without using & you'd be passing in a copy of your varaible, using a reference type string& you pass the actual variable in which is then modified by cin >> variable;.
P.S Don't use using namespace std;
You can't do this in C++.
You could have a std::map<std::string, SomeType> that you populate with your read-in names.
#pragma once
#include <iostream>
#include <map>
#include <string>
class Values
{
std::map<std::string, std::string> values;
public:
void askAndStore(std::string question, std::string name)
{
std::cout << question << " ";
std::cin >> values[name];
}
std::string get(std::string name)
{
return values[name];
// or return values.at(name); if name must already exist in values
}
};
int main()
{
Values user;
user.askAndStore("What is your name?", "usersName");
}
That assumes your values are std::strings
I have a issue about my constructor is not correctly working. Whenever i run the program, my overloaded operator might not be perform correctly because i always get the default constructor values when i get the output with cout.
I believe that i made my constructor declarations well but all of my objects getting filled with 0 and Unknown
here is my txt file:
1 Prince Heins 25
2 Lady Bridgette 29
3 Tony Ann 223
4 Lucy Phoenix 35
Here is my code;
#include <iostream>
#include <string>
#include <conio.h>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <istream>
#include <iomanip>
#include <cstring>
#include <ostream>
using namespace std;
class contact{
private:
int listno;
string name;
string surname;
string phonenumber;
public:
contact(){
this->name="Unknown";
this->surname="Unknown";
this->phonenumber="Unknown";
this->listno=0;
}
contact (string name,string surname,string phonenumber){
this->name=name;
this->surname=surname;
this->phonenumber=phonenumber;
}
contact(int listno,string name,string surname,string phonenumber){
this->name=name;
this->surname=surname;
this->listno=listno;
this->phonenumber=phonenumber;
}
friend ostream & operator<< (ostream &out, const contact &con){
out << con.listno << con.name << con.surname << con.phonenumber;
return out;
}
friend istream & operator>> (istream &in, contact &con){
in >> con.listno >> con.name >> con.surname >> con.phonenumber;
return in;
}
};
int main(){
ifstream pbin("phoneData2.txt");
string line;
long linecount;
for(linecount=0;getline(pbin,line);linecount++);
contact* myArray = new contact[linecount];
pbin.seekg(0);
if(pbin.is_open()){
int i;
for(i=0;i<linecount;i++){
if(pbin!=NULL){
while(pbin>>myArray[i]);
}
}
pbin.close();
cout << myArray[2]; // try attempt
return 0;
}
}
and here is my output for cout << Array[2];
OutputArray2
The problem results from the wrong used algorithm and wrongly placed statements.
So, let's look what is going on in the below:
long linecount;
for(linecount=0;getline(pbin,line);linecount++)
;
contact* myArray = new contact[linecount];
pbin.seekg(0);
if(pbin.is_open()){
int i;
for(i=0;i<linecount;i++){
if(pbin!=NULL) {
while(pbin>>myArray[i]);
}
}
pbin.close();
You want to count the lines. So you read all lines until the eofstate is set. But, additionally, also the fail bit will be set. See also here.
If you use your debugger, you will find a 3 in _Mystate.
Then you perform a seekg. This will reset the eof bit but keep the fail bit. The dubugger shows then
You can see that the fail bit is still set.
So, and this will now lead to the main problem. If your write if(pbin!=NULL) which is definitely wrong (on my machine is does not even compile), or if you better write if(pbin) the fail bit will still be set. And because the bool and the ! operator for streams is overwritten (please see here) the result of the if and while will be false and your pbin>>myArray[i] will never be executed.
So, a pbin.clear() would help.
But, although your class definition is already very good, with inserter and extractor overwritten, you do not use the full C++ power for reading the data.
One basic recommendation would be to never use raw pointers for owned memory. And best also not new. Use dedicated containers for your purpose. E.g. a std::vector. The you can use the std::vectors constructor no 5 together with a std::istream_iterator. Please read here. The range based constructor for the std::vector will copy data from a given range, denoted by the begin and end iterator. And if you use the std::istream_iterator, it will call your overwritten extractor operator, until all data are read.
So your main shrinks to:
int main() {
// Open source file and check, if it could be opened
if (ifstream pbin("r:\\phoneData2.txt");pbin) {
// Read complete source file
std::vector data(std::istream_iterator<contact>(pbin), {});
// Show data on console
std::copy(data.begin(), data.end(), std::ostream_iterator<contact>(std::cout, "\n"));
}
return 0;
}
This looks by far compacter and is easier to read. We start with an if-statement with initializer. The initializer parts defines the variable and the constructor will open the file for us. In the condition part, we simple write pbin. And, as explained above, its bool operator will be called, to check if everything was ok.
Please note:
We do not need a close statement, because the destructor of the
std::ifstream will close the file for us.
The outer namespace will not be polluted with the variable name pbin. That is one of the reasons, why ifstatement with initializer should be used.
We alread descibed the std::vector with its range constructor. SO reading the complete file is simple done by the very simple statement
std::vector data(std::istream_iterator<contact>(pbin), {});
Please note:
We do not define the type of the std::vector. This will be automatically deduced by the compiler through CTAD
We use the default initialzer {} for the end iterator, as can be seen here in constructor number 1.
The whole program could then be rewritten to:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
class contact {
private:
int listno;
string name;
string surname;
string phonenumber;
public:
contact() {
this->name = "Unknown";
this->surname = "Unknown";
this->phonenumber = "Unknown";
this->listno = 0;
}
contact(string name, string surname, string phonenumber) {
this->name = name;
this->surname = surname;
this->phonenumber = phonenumber;
}
contact(int listno, string name, string surname, string phonenumber) {
this->name = name;
this->surname = surname;
this->listno = listno;
this->phonenumber = phonenumber;
}
friend ostream& operator<< (ostream& out, const contact& con) {
out << con.listno << '\t' << con.name << '\t' << con.surname << '\t' << con.phonenumber;
return out;
}
friend istream& operator>> (istream& in, contact& con) {
in >> con.listno >> con.name >> con.surname >> con.phonenumber;
return in;
}
};
int main() {
// Open source file and check, if it could be opened
if (ifstream pbin("r:\\phoneData2.txt");pbin) {
// Read complete source file
std::vector data(std::istream_iterator<contact>(pbin), {});
// Show data on console
std::copy(data.begin(), data.end(), std::ostream_iterator<contact>(std::cout, "\n"));
}
return 0;
}
I have a string to be printed via a function. I am using turbo-c compiler.
While using procedural method I am able to do it from following code :
#include <iostream.h>
#include <conio.h>
void strr(char name[]);
void main(){
char name1[10];
cout << "Enter name";
cin >> name1;
strr(name1);
getch();
}
void strr(char name[]){
cout << name;
}
But With oop method I am not able to print the string. My Code is :
#include <iostream.h>
#include <conio.h>
class name{
public: void strr(char name[]);
};
void main(){
char name1[10];
cout << "Enter name";
cin >> name1;
strr(name1);
getch();
}
void name::strr(char name[]){
cout << name;
}
With oop method I am getting error Function 'strr' hould have a prototype.
Since your function is defined inside the class, you need an object/instance of the name class to invoke it :
name obj;
cin >> name1;
obj.strr(name1);
Alternatively, if you declare the function as static, then you can invoke it without a class-instance, since the function is a class-function :
class name{
public: static void strr(char name[]) {cout << name << endl;}
};
...
cin >> name1
name::strr(name1);
Try this
name :: void strr(char name[])
{}
I wanted to try to overload "<<" operator for an output stream and a custom class Article.
my.h
#include <iostream>
using namespace std;
class Article {
string body;
string header;
string author;
public:
Article();
void addHeader(const string&);
void addBody(const string&);
string getHeader();
string getBody();
};
my.cpp
string Article::getHeader() {
return header;
}
void Article::addBody(const string& body) {
this->body = body;
}
void Article::addHeader(const string& header) {
this->header = header;
}
ostream& operator<<(ostream& os, Article& article) {
return os << article.getHeader() << "\n\n" << article.getBody();
}
main.cpp
#include <iostream>
#include <string>
#include "my.h"
void main() {
char bye;
Article article = Article();
article.addBody("This is my article! thank you!");
article.addHeader("Header");
cout << article.getHeader() << "\n";
cout << article.getBody() << "\n";
cout << article;
cin >> bye;
}
This code doesn't compile. VS 2013 says:
binary '<<' : no operator found which takes a right-hand operand of type 'Article' (or there is no acceptable conversion)
If I remove the last line, it compiles successfully and the output of getHeader() and getBody() is as expected. They both return strings so it should be a piece of cake.
This problem seems very simple, however, as simple as it is I can't figure out what is happenning.
Now that you have posted real code the answer is obvious.
You define your operator << in my.cpp, but you don't declare it in my.h, so when compiling main.cpp the compiler has no way of knowing it exists.
Add a declaration of the function to your header.
I am unable to compile the following files.
I am trying to pass the name and age to an object and after checking and assigning each age to proper category(adult, kid...) then i am trying to print it.
My 3 files are following:
The first 1:
//cannot access private member declared in class Person
//No constructor could take the source type, or constructor overload resolution was ambiguous.
#include <iostream>
#include <string>
using namespace std;
#include "person2.h"
void getData(Person&);
void displayData(Person&);
int main(){
Person p;
getData(p);
displayData(p);
}
void getData(Person& p){
cout<< "Enter the name: ";
cin>> p.name;
cout<<"Enter the age: ";
int age;
cin>> age;
p.setAge(age);
p.ageGroup = p.determineAgeGroup(age);
}
void displayData(Person& p){
cout<<p.name<< " is in the group of " << p.ageGroup <<endl;
}
The second one:
#include <iostream>
#include <string>
using namespace std;
class Person {
public:
string name;
string ageGroup;
void setAge(int&);
string getAge();
string getAgeGroup(int);
private:
int age;
string determineAgeGroup(int );
};
The third one:
#include <iostream>
#include <string>
#include "person2.h"
using namespace std;
void Person::setAge(int& a){
if(a<0) cout<< "No";
}
string Person::getAge(){
return age;
}
string Person::determineAgeGroup(int a){
if(a>= 65) return "Senior";
else if(a<65 & a>= 20) return "Adult";
else if(a<20 & a>= 13) return "Teen";
else return "Kid";
}
string Person::getAgeGroup(int a){
return determineAgeGroup(a);<<endl;
}
Check the following:
endl instead of end in displayData
declare int age in getData and pass that value to p.setAge
return value from getAge should be an int
make determineAgeGroup() public or call determineAgeGroup() from a member function like setAge() or call your public function getAgeGroup().
This should at least get you compiling...
Note: The final edit that solved the problem was bullet point number 4, in particular calling the public function getAgeGroup().