Trying to convert a string into a int using stringstream - c++

I'm trying check if a string representation equals given integer. I'm meant to use stringstream for this in a function. I also have an operator= for this as well.
I'm a little confused on how to execute these together and if I'm missing something. This is the last bit to an assignment I have, this is just a small snippet of my whole program. I can't find many guides on this, and I sense they all direct me to atoi or atod, which I'm not allowed to use.
#ifndef INTEGER
#define INTEGER
using std::string;
class Integer
{
private:
int intOne;
string strOne;
public:
Integer() {
intOne = 0;
}
Integer(int y) {
intOne = y;
}
Integer(string x) {
strOne = x;
}
void equals(string a);
Integer &operator=(const string*);
string toString();
};
#endif
In this header I'm not sure what argument I'm to use for the = operator.
#include <iostream>
#include <sstream>
#include <string>
#include "Integer.h"
using namespace std;
Integer &Integer::operator=(const string*)
{
this->equals(strOne);
return *this;
}
void Integer::equals(string a)
{
strOne = a;
toString(strOne);
}
string Integer::toString()
{
stringstream ss;
ss << intOne;
return ss.str();
}
#include <iostream>
#include <cstdlib>
#include <conio.h>
#include <string>
#include <ostream>
using namespace std;
#include "Menu.h"
#include "Integer.h"
#include "Double.h"
int main()
{
Integer i1;
i1.equals("33");
cout << i1;
}
Sorry if its a bad question I'm not too familiar with this type of assignment and will take any help I can get. Thanks.

you can use std::to_strig() that lets you convert from int to a string that represents the same number.

So if i understand correctly, you want to overload operator =, and that is a bad idea, since operator= is used for assignment not for comparison.
The correct operator signature is:
ReturnType operator==(const TypeOne first, const TypeSecond second) [const] // if outside of class
ReturnType operator==(const TypeSecond second) [const] // if inside class
Since you can't compare string to integer (they are different types), you need to write your comparisment function, since you don't have one i will write one for you:
bool is_int_equal_string(std::string str, int i)
{
std::string tmp;
tmp << i;
return tmp.str() == i;
}
Last but not least, you need to merge both of those, into one convenient operator:
// inside your Integer class
bool operator==(std::string value) const
{
std::stringstream tmp;
tmp << intOne;
return tmp.str() == ref;
}
Now you can use this operator, just like any other:
Integer foo = 31;
if (foo == "31")
cout << "Is equal" << endl;
else
cout << "Is NOT equal" << endl;
I hope this helps.

If you are allowed to use std::to_string then it would be the best.
Otherwise, you could create a function to handle the equality between the string and the integer with the use of std::stringstream:
Example:
bool Integer::equal(const string& str)
{
stringstream ss(str);
int str_to_int = 0;
ss >> str_to_int;
if (intOne == str_to_int)
return true;
else
return false;
}
Combine this with an if statement:
int main()
{
Integer i{100};
if (i.equal("100"))
cout << "true" << endl;
else
cout << "false" << endl;
}

Related

Pointers to undefined functions and parameters in C ++

I have the following code:
#include<iostream>
using namespace std;
void saludo();
void despedida();
int main(){
void (*Ptr_Funciones[2])() = {saludo, despedida};
(Ptr_Funciones[0])();
(Ptr_Funciones[1])();
return 0;
}
void saludo(){
cout<<"\nHola mundo";
}
void despedida(){
cout<<"\nAdios mundo"<<endl<<endl;
}
Based on this, a few questions were generated which I investigated before asking but did not fully understand.
The questions are:
How do I make an array of functions, if they are of a different type?
I know that in C ++ this notation is used for undetermined parameters: (type var ...) The
thing is, I don't know how to interact with them inside the function.
If questions 1 and 2 are possible, can these points be combined when creating function
arrays?
I really have investigated. But I can't find much information, and the little I did find I didn't understand very well. I hope you can collaborate with me.
Thank you very much.
How do I make an array of functions, if they are of a different type?
You can, but you don't want to. It doesn't make semantic sense. An array is a collection of the same kind of thing. If you find that you need to make a collection of different kinds of things, there are several data structures at your disposal.
I know that in C++ this notation is used for undetermined parameters: (type var ...) The thing is, I don't know how to interact with them inside the function.
Here's how you can use the syntax you mention. They're called variadic functions.
If questions 1 and 2 are possible, can these points be combined when creating function arrays?
Erm, I can't imagine why/when a combination of these two would be needed, but out of intellectual curiosity, awayyy we go...
A modified version of the code from the reference link above that kinda does what you want (i've used a map instead of an array, cuz why not):
#include <iostream>
#include <cstdarg>
#include <unordered_map>
template<typename T>
using fooptr = void (*) (T *t...);
struct A {
const char *fmt;
A(const char *s) :fmt{s} {}
};
struct B : public A {
B(const char *s) : A{s} {}
};
void simple_printf(A *a...)
{
va_list args;
auto fmt = a->fmt;
va_start(args, a);
while (*fmt != '\0') {
if (*fmt == 'd') {
int i = va_arg(args, int);
std::cout << i << '\n';
} else if (*fmt == 'c') {
// note automatic conversion to integral type
int c = va_arg(args, int);
std::cout << static_cast<char>(c) << '\n';
} else if (*fmt == 'f') {
double d = va_arg(args, double);
std::cout << d << '\n';
}
++fmt;
}
va_end(args);
}
int main()
{
A a{"dcff"};
B b{"dcfff"};
std::unordered_map<size_t, fooptr<struct A>> index;
index[1] = simple_printf;
index[5] = simple_printf;
index[1](&a, 3, 'a', 1.999, 42.5);
index[5](&b, 4, 'b', 2.999, 52.5, 100.5);
}
This still really doesn't do what you wanted (i.e., give us the ability to choose from different functions during runtime). Bonus points if you understand why that's the case and/or how to fix it to do what you want.
Use a type alias to make things readable:
Live On Coliru
using Signature = void();
Signature* Ptr_Funciones[] = { saludo, despedida };
Prints
Hola mundo
Adios mundo
More flexible:
You can also use a vector:
Live On Coliru
#include <iostream>
#include <vector>
using namespace std;
void saludo() { cout << "\nHola mundo"; }
void despedida() { cout << "\nAdios mundo" << endl << endl; }
int main() {
vector Ptr_Funciones = { saludo, despedida };
Ptr_Funciones.front()();
Ptr_Funciones.back()();
}
Prints the same.
More Flexibility: Calleables of Different Types
To bind different types of functions, type-erasure should be used. std::function helps:
Live On Coliru
#include <iostream>
#include <functional>
#include <vector>
using namespace std;
void saludo(int value) { cout << "\nHola mundo (" << value << ")"; }
std::string despedida() { cout << "\nAdios mundo" << endl << endl; return "done"; }
int main() {
vector<function<void()>>
Ptr_Funciones {
bind(saludo, 42),
despedida
};
Ptr_Funciones.front()();
Ptr_Funciones.back()();
}
Prints
Hola mundo (42)
Adios mundo
Here is one solution that is possible, whether it fits your needs I'm not sure.
#include <Windows.h>
#include <iostream>
void saludo()
{
std::cout << "\nHola mundo" << std::endl;;
}
void despedida()
{
std::cout << "\nAdios mundo" << std::endl;
}
void* fnPtrs[2];
typedef void* (VoidFunc)();
int main()
{
fnPtrs[0] = saludo;
fnPtrs[1] = despedida;
((VoidFunc*)fnPtrs[0])();
((VoidFunc*)fnPtrs[1])();
std::getchar();
return 0;
}

C++: How to make function return only strings which are a part of a list?

I want my function to return a string, but only strings which are a member of a specific list/set of strings. How can I go about doing this?
You do not want to return a string, you want to return a string that has an additional restriction (being part of some predefined set).
For that you'd need a new type:
class BusinessStringWrapper {
public:
BusinessStringWrapper(std::string arg): value{arg} {
if (/* arg is not ok */) {
throw;
}
}
// you can replace that with factory method
// can also return std::optional instead of throwing if the condition is not met
// that depends on your application
std::string value() const { return value; }
private:
const std::string value;
};
And in your application you'd operate on this type, accessing value if needed.
Hoe about using a std::set<std::string>?
#include <iostream>
#include <set>
#include <string>
std::string helper(const std::string & str,
const std::set<std::string> & lst)
{
return lst.find(str) == lst.end() ? "" : str;
}
int main()
{
std::set<std::string> lst = {"alpha", "beta", "gamma"};
std::cout << "return " << helper("alpha", lst) << "\n";
std::cout << "return " << helper("zeta", lst) << "\n";
return 0;
}
Output
return alpha
return
Of course, it really depends on what your definition of does not return is.
If it means an empty string, then use the above solution. Keep your life simple.
If it means an error and the program should terminate, you may #include <cassert> and just
assert(lst.find(str) != lst.end());
If it means an exception to handle, you may try throw and catch.
If it means returning a std::string if str is in a predefined list, but a void if it's not, then you may need some tricks as described in <type_traits>.
You can do this std::map<CardType, std::string> in the example below, or use std::map<int, std::string> to associate a string with any integer. For example mp[123]="abcd"
#include <iostream>
#include <string>
#include <map>
enum CardType {
SPADE,
HEART,
CLUBS,
DIAMD
};
std::map<CardType, std::string> mp{
{CardType::SPADE, "Spade"},
{CardType::HEART, "Heart"},
{CardType::CLUBS, "Clubs"},
{CardType::DIAMD, "Diamond"}
};
int main()
{
std::cout << mp[CardType::SPADE] << std::endl;
return 0;
}

How to convert std::string to any of several types in constructor?

I have the following class template which has a member variable whose type is determined by the template argument. I want to initialize the value of this member in the constructor, which only takes a std::string. Thus, my problem is that I need to convert std::string to any of several types (int, double, bool, string). I don't think I can specialize just the constructor, and I would rather not specialize the entire class for each type. The problem with my code below is that stringstream stops streaming out when it hits a space:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
template <typename Ty>
struct Test
{
Ty value;
Test(string str) {
stringstream ss;
ss.str(str);
ss >> value;
}
};
int main()
{
Test<int> t1{"42"};
Test<double> t2{"3.14159"};
Test<string> t3{"Hello world"};
cout << t1.value << endl << t2.value << endl << t3.value << endl;
return 0;
}
The output of the above code is:
42
3.14159
Hello
instead of "Hello world". Is there some way to get stringstream to not stop at whitespace, or some other device that will do arbitrary conversions like I need?
This works for me. Just declare a special implementation before the generalized implementation:
#include <iostream>
#include <string>
#include <sstream>
template<typename T>
struct Test {
T value;
Test(std::string);
};
template<>
inline Test<std::string>::Test(std::string str) {
value = str;
}
template<typename T>
inline Test<T>::Test(std::string str) {
std::stringstream ss;
ss.str(str);
ss >> value;
}
int main() {
Test<int> t1{"42"};
Test<double> t2{"3.14159"};
Test<std::string> t3{"Hello world"};
std::cout
<< t1.value << std::endl
<< t2.value << std::endl
<< t3.value << std::endl;
return 0;
}
Here is an ideone working example.

C++ return 0 when initial a class fail

i was writing a class like this
class AA{
private:
char* str;
public:
AA(int size){
str = (char*)malloc(size);
}
};
int main(){
AA anAA(1000);
}
here is the problem, when the size is too big it may cause malloc return a 0 pointer, if the str init fail, is there any method to return a 0 pointer to anAA(in the main entry point, i can check anAA isn't init success by if(anAA != NULL)), i don't want to make a function for creating AA class, or make a check function in the class
I'll ignore the atrocities you are committing in favour of answering your question.
The easiest solution, if you don't want to use exceptions, is to define an operator bool():
class AA{
...
public:
operator bool() const {
return this->str != nullptr; // return str; would actually suffice
}
};
int main(){
AA anAA(1000);
if (!anAA) {
std::cerr << "Creating object failed.\n";
return 1;
}
return 0;
}
#include <iostream>
#include <stdexcept> // std::exception
#include <stdlib.h> // EXIT_FAILURE
#include <string> // std::string
#include <vector> // std::vector
using namespace std;
class AA{
private:
string str_;
public:
AA( int const size)
{
str_.reserve( size );
}
};
int main()
{
try
{
AA anAA( 1000 );
// Whatever
}
catch( exception const& x )
{
cerr << "!" << x.what() << endl;
return EXIT_FAILURE;
}
}
Note 1: with this approach you probably don't need to reserve a size upfront.
Note 2: I chose reserve as probably the closest thing to a presumed intention of making sure that str_ can hold at least that long a string without failure, a preallocation of resources.
Disclaimer: I've not compiled this code.

C++ ostringstream strange behavior when chaining in cout is used

I am a C++ beginner ( came from Java ). I have the following code:
//#include <boost/algorithm/string.hpp>
#include <iostream>
#include <math.h>
#include <vector>
#include <string.h>
#include <string>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <memory>
#include <assert.h>
#include <cctype>
using namespace std;
class Point{
private:
int x;
int y;
public:
Point(int x,int y){
this->x=x;
this->y=y;
}
int getX(){
return x;
}
int getY(){
return y;
}
operator const char*(){
return toString().c_str();
}
string toString(){
ostringstream stream;
stream<<"( "<<x<<", "<<y<<" )";
return stream.str();
}
};
class Line{
private:
Point p1=Point(0,0);
Point p2=Point(0,0);
public:
Line(Point p1, Point p2){
this->p1=p1;
this->p2=p2;
}
Point getP1(){
return p1;
}
Point getP2(){
return p2;
}
operator const char*(){
ostringstream stream;
stream<<"[ "<<p1<<" -> "<<p2<<" ]";
return stream.str().c_str();
}
// operator const char*(){
// ostringstream stream;
// stream<<"[ "<<p1<<" -> ";
// stream<<p2<<" ]";
// return stream.str().c_str();
// }
};
int main()
{
Line line=Line(Point(1,2), Point(3,4));
cout<<line<<endl;
cout<<"\nProgram exited successfully."<<endl;
return 0;
}
I have redefined the operator const* so that I can use cout<
But, If I run the program as it is now, with the second block commented out ( I have 2 versions of operator const*, and by default the second one is commented out ) ,it will display
[ (1, 2) -> (1, 2) ]
But when running with the second block uncommented, the output is as expected:
[ (1, 2) -> (3, 4) ]
The issue seems to occur when I display both Point objects in the same line ( some kind of chaining, though I don't know if chaining is the right word here )
My question, is,why is this happening?
UPDATE
I have added the std::ostream& operator << function to my Line class but now I'm receiving the following errors:
/home/ryu/qt_workspace/hello/main.cpp:67: error: 'std::ostream& Line::operator<<(std::ostream&, const Line&)' must take exactly one argument
/home/ryu/qt_workspace/hello/main.cpp:77: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
Regards,
Aurelian
If you want to use cout <<, there is a more direct way to do that.
Add this function to Line.
friend std::ostream& operator << ( std::ostream & os, const Line & l ){
os << "[ " << l.p1 << " -> " << l.p2 << " ]";
return os;
}
You should also note that your approach was returning invalid memory - this is a significant way that Java differs from C++.
return stream.str().c_str(); // Danger!
stream was declared in operator const char*() which limits its lifetime to that function. It is destroyed when that scope is exited. As a result, you are returning a pointer to something that no longer exists.
actually I think with C++11 returning the string by value is perfectly fine, so you can do the transfer there instead of using the cstring underneath.
What are move semantics?