Convert STRING into INT

Hi!
I need to create a program for an assignment that, between it's capacities, has to take an string and convert it into an int.

Example: If I recieve:

string placa=BXH789 (User fills with numbers and letters)

I would need the program to assign the value to n as:

int n=789

I've already tried with stringstream:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  #include <sstream>
#include <iostream>
using namespace std;

int main(int argc, char *argv[]) {
	string placa;
	int n;
	
	cin>>placa;
	
	stringstream ss;
	ss<<placa;
	ss>>n;
	
	cout<<n;
	
	return 0;
}

And with stoi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <string> 
#include <iostream>
using namespace std;

int main(int argc, char *argv[]) {
	string placa;
		
	cin>>placa;
	
	int n=stoi(placa);
		
	cout<<n;
	
	return 0;
}

...,but they only work if the numbers are in the first position.

Example SS:
string placa= 778ASD
n would be<<778
but if string placa=ASD778
n would be=0

Example STOI:
string placa=778ASD
n would be<<778
but if string placa=ASD778
n would be<<terminate called after throwing an instance of 'std::invalid_argument'
what(): stoi

Can you help me to understand why isn't it working? Thanks!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int get_model_number(const std::string &s){
    static const char * const digits = "0123456789";
    auto digit = s.find_first_of(digits);
    if (digit == std::string::npos)
        return -1; //string doesn't contain any numbers
    auto last = s.find_first_not_of(digits, digit);
    auto s2 = last == std::string::npos ? s.substr(digit) : s.substr(digit, last - digit);
    std::stringstring stream(s2);
    int ret;
    stream >> ret;
    return ret;
}

//...

std::cin >> input;
n = get_model_number(input);
Last edited on
It's because
1. stoi won't convert letters to integers. It just doesn't work (as far as I know).
2. Letters in stringstream won't convert to integers like that.

What you need to do is use a for loop and iterate through the string, probably use isalpha() or isdigit() to figure out if each individual element is a character or an integer.

Example (some hastily thrown-together code)
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
37
38
39
40
#include <iostream> // good idea to include this first
#include <string>
#include <cstring> // needed to use c-string functions
#include <cctype> // needed to use isalpha() and isdigit()

int main () 
{
	int integer {};
	
	std::string placa {};
	
	char cplaca[256] {'\0'};
	char nums[10] {'\0'};
	
	std::cout << "Enter placa. \n: ";
	std::cin >> placa;
	
	strcpy (cplaca, placa.c_str() ); // convert std::string to c-string
	
	int counter {0};
	
	for (unsigned i = 0; i < placa.size(); ++i) // This is the main thing; just iterates through the c-string
	{					    // and puts any numbers it finds into the c-string nums[]
		if (isdigit ( placa.at(i) ) )
		{
			nums[counter] = cplaca[i];
		}
		else
		{
			continue;
		}
		++counter;
	}
	
	integer = atoi (nums); // use atoi() to convert nums[] to int
	
	std::cout << integer << std::endl;
	
	return 0;
}

I know that's not the neatest way to do it, but I was trying to explain it a bit more.
Hope that helps!
max
Thanks to both of you, I was able to complete my task with what you said and learnt something I think is gonna be really useful!

PD: Agent Max, I know it's just a way to write it, but why do you add"{}" after declaring the varibles? Is it only a stetical thing or does it do something? I just started programming a month ago and had never seen that. Ty!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
#include <cctype>
#include <sstream>

int main()
{
	int integer {-1};
	std::string placa;

	std::cout << "Enter placa: ";
	std::cin >> placa;

	std::istringstream iss(placa);

	for (; iss && !std::isdigit(static_cast<unsigned char>(iss.peek())); iss.ignore());

	if (iss)
		iss >> integer;

	std::cout << integer << '\n';
}

Last edited on
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
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;

long long grabDigits( const string &str, bool all=false )
{
   if ( all )
   {
      string result;
      copy_if( str.begin(), str.end(), back_inserter( result ), ::isdigit );
      return result.empty() ? -1 : stoll( result );
   }
   else
   {
      size_t p = str.find_first_of( "0123456789" );
      return p == string::npos ? -1 : stoll( str.substr( p ) );
   }
}

int main()
{
   string placa = "ABCD123EFG456H";
   cout << grabDigits( placa ) << '\n';
   cout << grabDigits( placa, true ) << '\n';
   cout << grabDigits( "abc" ) << '\n';
   cout << grabDigits( "abc", true ) << '\n';
}


123
123456
-1
-1
Last edited on
PD: Agent Max, I know it's just a way to write it, but why do you add"{}" after declaring the varibles?
It initializes the variable to the default value. For numeric values it is 0.
{} isn't needed for a class with a default constructor. Also for char, the default is 0 so {'\0'} can be just {}. The default for int is 0 and for double 0.0 so int{0} is just int{}.

seeplus wrote:
{} isn't needed for a class with a default constructor. Also for char, the default is 0 so {'\0'} can be just {}.

It's just kind of gotten into a habit. As for the char, that was how my textbook said to do it. I wasn't sure if I could just use {} or not.
Topic archived. No new replies allowed.