string to int

Hello,
I am facing problems to convert a string(consisting of digits only) to an int variable...as no mathematical operations can be done in a string so, I have to convert it to int and do the operations...but somehow I am not getting a desirable output...

My code goes as follows...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<iostream>
#include<conio.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<math.h>

using namespace std;

int main()
{
    system("cls");
    char c[5];
    int i,n,d,num=0;
    cout<<"Enter a number (which is to be saved as a string): ";
    gets(c);

    n=strlen(c);
    d=n-1;
    for(i=0;i<n;i++,d--)
        num+=(pow(10,i)*c[d]);

    cout<<"Your number (which is as int) is "<<num;
    cout<<endl<<"100 added to the number you entered is: "<<num+100;
    getch();
    return 0;
}


The output is like follows...
Enter a number (which is to be saved as a string): 512
Your number (which is as int) is 5840
100 added to the number you entered is: 5940

This is extremely undesirable... :(

Note: I am just a beginner with a few knowledge in functions, structures, etc...A quick and an easy help within my boundaries is highly appreciable...

Thanks in advance,
Regards...


Update: Sorry...the code<> function is not actually working out here...please pardon me...
Last edited on
First never use gets(), this dangerous function can never be used safely. Since you seem to be using C++ prefer c++ strings and getline() or the extraction operator.

Then once you have your "number" in the string you can use stoi() to convert the string to an actual number.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>

using namespace std;

int main()
{
    string value;

    cout << "Please enter a number: ";
    cin >> value;

    int number;

    // Convert the number into a string.
    number = stoi(value);

    cout << number << endl;


    return 0;
}


Or just get the numeric value directly into the correct type of variable instead of the string.


Thanks for your reply @jib...

Isn't there a way without stoi()...

Take for example...
A temperature conversion program...
Where the user enters 100C...means 100-degree celsius
100F...means 100-degree Fahrenheit
100K...means 100 Kelvin

I would take 100C or 100F or 100K as input in a string...
And then use a logic to check the last char (C/F/K) and implement the code accordingly...
The program would instantly get information(s) about temp from this string...

So...here I have to only convert the chars (before the last char i.e. expect C/F/K) into int...
So here how can I implement stio()...

This was just an example of how i would implement string to int conversions...

Again...
Thanks in advance,
Regards...
Maybe so:
1
2
3
4
5
6
7
8
9
10
11
12
13
int main() 
{
  int temperature = 0;
  char type = 0;
  
  cout << "Enter temperature: ";
  cin >> temperature >> type;
  
  cout << "temperature: " << temperature <<  "\ntype: " << type << "\n\n";

  system("pause");
  return 0;
}


OUTPUT
Enter temperature: 33C
temperature: 33
type: C
Thanks for your reply @Thomas1965...

Your way of thinking and executing the task is no way wrong...but actually, i want to do the same task another way round...

A program can be written in more than one way...I just want the way I stated...because I am going to apply this code in other programs also where your way won't work... :(

So if you can help me out in my way please help me...if not you may better suggest other ways close to my one... :)

Again...
Thanks in advance,
Regards...

The easiest and safest way is to probably to go from string to stringstream to int (or any other type). The intermediate stringstream can also be used to get numerical and unit parts as in @Thomas1965's example. General converters doing this (for arbitrary numerical types) are toString() and fromString() below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

//============================

template <class T > string toString( T value )
{
   stringstream ss;
   ss << value;
   return ss.str();
}

//============================

template <class T > T fromString( string s )
{
   T value;
   stringstream ss( s );
   ss >> value;
   return value;
}

//============================

int main()
{
   string s;

   s = "13045";
   int i = fromString<int>( s );   cout << i << endl;

   double d = 3.14159;
   s = toString( d );   cout << "[" << s << "]" << endl;
}



If you wish to pick off the digits as in your code then you can use the sample below. It works for positive integers, with no leading or trailing blanks. To be generally useful, you should extend it to (amongst other things):
- ignore any leading or trailing blanks
- deal with a minus (or even a plus) sign
- check that there is only one integer in the string
- check that the string only contains valid characters
- check that the resulting integer doesn't exceed numerical limits.
These would make the code sample extremely long.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<iostream>
#include<string>
using namespace std;

int stringToInt( string s )
{
   int result = 0;                               // to hold the integer result

   for ( int i = 0; i < s.size(); i++ )          // loop through characters of string
   {
      int digit = s[i] - '0';
      result = 10 * result + digit;
   }

   return result;
}

//============================

int main()
{
   string s = "12345";
   int i = stringToInt( s );

   cout << "String is " << s << "   Integer is " << i << endl;
}
Update: Sorry...the code<> function is not actually working out here...please pardon me...

That's because you haven't done the tags right. You use square brackets - [ ] - not angle brackets.
Thanks for your reply @lastchance...

Note: I am just a beginner with a few knowledge in functions, structures, etc...A quick and an easy help within my boundaries is highly appreciable...

Sorry, for that...But I have not yet learned classes and templates...so I couldn't understand your first program...

The second programming is quietly appreciable...but a part of it I couldn't understand...

1
2
int digit = s[i] - '0'; //line no. 11 in your code
//What are you actually doing out here?? i cannot understand 


...especially s[i] - '0' ...why are you subtracting '0' (i.e. zero as an char)...is it possible...

is your code analogous with mine...

1
2
3
4
5
6
//my code
n=strlen(c);
d=n-1;

for(i=0;i<n;i++,d--)
    num+=(pow(10,i)*c[d]);


Where is my mistake?...
You may refer to my code in the beginning of the thread...

Again...
Thanks in advance,
Regards...
Thanks for your reply @MikeyBoy...

It was absolutely my error...but though...thanks for it...i updated it...

But can you help me with my problem...if yes then please help me...

Again...
Thanks in advance,
Regards...
@kinjal2209

This is the stringstream version of fromString(), with comments, without templating. All the templates do is allow you to use the same routine for other types T (like float, double, etc.)

For stringstream, see http://www.cplusplus.com/reference/sstream/stringstream/
and look at the constructor or member functions for examples.

Using a stringstream as a repository - getting the data from a string, sending it back as an integer - is probably the easiest and safest way for you. It acts rather like a disk file, but instead is an area of internal computer memory.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <sstream>
#include <string>
using namespace std;


int fromString( string s )        // takes a string s and returns an integer equivalent
{
   int value;                     // this will hold the final integer value

   stringstream ss( s );          // create a stringstream from s ... this is like writing s to a "file" or cout,
                                  // but instead it is in computer memory

   ss >> value;                   // now read back from the stringstream, but this time into the integer value

   return value;                  // return this integer from the program
}



int main()                        // just to test it
{
   string s = "13045";
   int i = fromString( s );   cout << i << endl;
}



My second example worked a bit like yours, in that it picked off individual characters one by one.

Note that a char has an equivalent integer representation, and they are in alphanumeric order. Thus, successive characters (NOT digits) '0', '1', '2', ... will have successive equivalent integers (although these numbers may not be the same on all computers) and when you operations + and - on them you will be operating on those integers. Thus, for example,
'3' - '1' produces the integer 2, irrespective of the actual number attached to char '1'. Then
s[i] - '0' will produce the integer digit associated with s[i] - which is what is needed.

Numbers are then built up as follows. Note that we read strings from left to right.
Suppose the string is "12345".
result -> 1
Then multiply by 10 and add the next digit:
result -> 10 + 2 = 12
Then multiply by 10 and add the next digit:
result -> 120 + 3 = 123
Then multiply by 10 and add the next digit:
result -> 1230 + 4 = 1234
Then multiply by 10 and add the next digit:
result -> 12340 + 5 = 12345
This is a common way of building up numbers like this incrementally.

In your own code you use pow(10,i) because you think that this will work the same way as 10^(i) EXACTLY. One problem with this (apart from inefficiency, given the way pow() computes) is that the answer is a double and, unlike an int, this is stored only to a certain accuracy. Try to assign it to an int and you round TOWARD ZERO (not the nearest integer). Thus, for example, you might get 99999.9 which actually rounds down to 99999 and this is clearly not what you want.

The other major problems with your code is that you are using C-style headers and C-strings. The latter has its uses, but a string is more convenient here (and, probably, in most other places).

Hope this rambling explanation helps.

Thanks for your reply @lastchance...
...and sorry for replying late... :(

Hope this rambling explanation helps.

Yeah...That explanation helped me a lot...but one last thing that is...
is it correct to use string stream with floating point numbers...

such as the string be 12345.67 and this is saved into a float variable...
is it possible...

Again...
Thanks in advance,
Regards...
Last edited on
is it correct to use string stream with floating point numbers...


Certainly. It's just like any other input stream (such as cin, or an input filestream), except that here it originates in a string. I often use stringstream when I'm reading lines from file: getline() a whole line into a string first, then use stringstream to distribute that into individual elements.

You could just change int to float in my last function fromString() above. However, you would need a separate name of function if you wanted to convert to both ints and floats. Much better is to use a SINGLE TEMPLATE function as below. It's quite straightforward: T just stands for the type (int, float, double) etc.
template <class T > T
simply replaces
int
as the return type of the function. T just stands for a generic type. Often (but not here) T can refer to the argument types and also (as here) to internal variables such as value. There's actually nothing special about the letter T - you could have used any other - but grammatically I can easily associate T with Type. Other people also use "typename" instead of "class", thus:
template <typename T > T
They are completely equivalent, so take your pick.

You can call the function as
1
2
3
fromString<int>( s );
fromString<float>( s );
fromString<double>( s );

to get int, float, double etc ... but the key thing is that you only have to write a single function to do all of them.

(One last minor point - the default precision on an output stream is 6, so a string "12345.67" will be written, unless you change the precision, as 12345.7 (i.e. 6 sig figs). If you want higher precision you will need to set the output stream precision (e.g. using an io manipulator) as necessary. This is only an issue of how the program writes your output, NOT how it converted from string to double or float.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
using namespace std;

//============================

template <class T > T fromString( string s )
{
   T value;
   stringstream ss( s );
   ss >> value;
   return value;
}

//============================

int main()
{
   string s;

   s = "12345";
   int i = fromString<int>( s );   cout << "Integer from string: " << i << endl;

   s = "3.14159";
   float f = fromString<float>( s );   cout << "Float from string: " << f << endl;

   s = "2.71828";
   double d = fromString<double>( s );   cout << "Double from string: " << d << endl;
}


Integer from string: 12345
Float from string: 3.14159
Double from string: 2.71828
Last edited on
Thanks for your reply @lastchance...

I get what you say about template...though I have not studied it at all but this 'T' seems to a universal datatype which can take up and use different datatypes as per requirements in different levels in a code...(am I correct...)

Okay...but what you would do if the input like be... 12345.67C
Then the input should be taken as a string and the number(12345.67) would be saved in a float(or double) and the last character(C) would be saved in a char...

//This was in my temperature program...

Then how can you implement stringstream here..to do the above task...

Another thing:
can't I use char[50] in place of string in all the above programs...
after all, an array of character and a string is the same thing...yeah...(am I correct...)

Again...
Thanks in advance,
Regards...
Last edited on
Okay...but what you would do if the input like be... 12345.67C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

using namespace std;


int main()
{

    double number;
    char ch;
    
    cin >> number >> ch;
    
    cout << "number = " << number << "\ncharacter = " << ch << '\n';

} 
12345.67C
number = 12345.7
character = C

Whether one is reading from a file, or from a stringstream or from the standard input cin, the principle would be the same.
1
2
3
4
5
6
7
8
    double number;
    char ch;
    
    istringstream ss("12345.67C");
    if (ss >> number >> ch)
    {
        cout << "number = " << number << "\ncharacter = " << ch << '\n';
    }

Thanks for your reply @Chervil...

but... what is istringstream...

And why do you use an if statement to display the values... unlike @lastchance...directly...

1
2
3
istringstream ss("12345.67C");
ss >> number >> ch;
cout << "number = " << number << "\ncharacter = " << ch << '\n';

Again...
Thanks in advance,
Regards...


but... what is istringstream...

It is an input stream, just like a disk file or like the keyboard input cin. They all behave in the same way. the stringstream stores its content in an internal string. It requires the header #include <sstream>
I came to this thread quite late, and notice from the original post it seems you are using Turbo C++, isn't that so? In which case, you won't be able to use either strings or stringstreams, I highly recommend using a more recent compiler if at all possible (I know some college courses still use it - which is rather a shame, in my opinion).

And why do you use an if statement to display the values...

It is an extra check. It validates that the input was successful. You could do it instead like this:

1
2
3
4
5
6
7
8
9
10
11
    istringstream ss("12345.67C");
    ss >> number >> ch;

    if ( !ss.fail() )
    {
        cout << "number = " << number << "\ncharacter = " << ch << '\n';
    }
    else
    {
        cout << "Input was not valid\n";
    }


Of course you could omit the check on ss.fail(), but then there is no way of telling whether the contents of number and ch are meaningful or just garbage.

Thanks for your reply @Chervil...

Yeah i understand...what you say...

it seems you are using Turbo C++, isn't that so? In which case, you won't be able to use either strings or stringstreams,

Can you recommend me any other latest compiler... Actually we use turbo on our school...i personally don't like it though...

I tried using string in turbo... But i returns me with error...
My teacher asked me to use char [size] instead of string...

Can i use stringstream with char [size]...
I used Turbo C++ 25 years ago and it was the best C++ compiler for DOS, but times have changed.
However it might be worth to have a look at the examples, if your version has them. They showed good coding practices and I learned more from them than from our teacher in school.

If it doesn't support std::string it probably doesn't have std::stringstream either.
@kinjal2209.

Is this what you want? You will probably need to modify it for your specific needs (float for double or whatever).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <sstream>                     // stringstream header
using namespace std;

//============================

void getTemperature( const char *charTemp, double &temperature, char &unit )
{
   stringstream ss;                    // create empty stringstream
   ss << charTemp;                     // input the character array
   ss >> temperature >> unit;          // output the temperature and unit
}

//============================

int main()
{
   double temp;
   char unit;

   // Test 1
   getTemperature( "100C", temp, unit );   cout << "Temperature: " << temp << " degrees " << unit << endl;

   // Test 2
   char arr[] = "273 K";
   getTemperature( arr   , temp, unit );   cout << "Temperature: " << temp << " degrees " << unit << endl;
}

Temperature: 100 degrees C
Temperature: 273 degrees K


For some C++ compilers (and other info) see https://isocpp.org/get-started
or just google "free c++ compiler".

On the other hand, the tutorial on this website is outstanding, as is the accompanying reference.

Last edited on
Hello Again...
Sorry for that...I was late in getting back to this thread because of my final examinations...but they are now over and I am free to hang around with lots and lots of codes...

Thanks, everyone out here...I, at last, got the problem solved...just because of you all...thanks a lot again... :)

Here I would take the opportunity to congratulate you all as a part of my thread...
@jlb
@Thomas1965
@lastchance
@MikeyBoy - though little but useful...
@Chervil

the last explanation by @lastchance was absolutely clear for me...I, at last, cracked the code...

Warm Regards from my side...
Thanking you...
Closing the thread here!!!... :)
Topic archived. No new replies allowed.