user2904033
user2904033

Reputation: 131

A cleaner way to convert a string to int after checking for hex prefix?

This little exercise is meant to get a string from the user that could be decimal, hexadecimal, or octal. 1st I need to identify which kind of number the string is. 2nd I need to convert that number to int and display the number in its proper format, eg:

cout <<(dec,hex,oct, etc)<< number;

Here's what I came up with. I'd like a simpler, cleaner way to write this.

string number = "";
cin >> number;
string prefix = "dec";
char zero = '0';
char hex_prefix = 'x';
string temp = "";
int value = 0;

for(int i =0; i<number.size();++i)
{
    if(number[0] == zero)//must be octal or hex
    {
        if (number[0] == zero && number[1] == hex_prefix ) //is hex
        {
            prefix = "hex";
            for(int i = 0; i < (number.size() - 2); ++i)
            {
                temp[i] = number[i+2]; 

            }
            value = atoi(temp.c_str()); 
        }
        //... code continues to deal with octal and decimal

Upvotes: 1

Views: 230

Answers (4)

anatolyg
anatolyg

Reputation: 28241

This partial solution that I found is as clean as possible, but it doesn't report the format of the integer:

int string_to_int(std::string str)
{
    std::istringstream stream;
    stream.unsetf(std::ios_base::dec);
    int result;
    if (stream >> result)
        return result;
    else
        throw std::runtime_error("blah");
}

...

cout << string_to_int("55") << '\n';   // prints 55
cout << string_to_int("0x37") << '\n'; // prints 55

The point here is stream.unsetf(std::ios_base::dec) - it unsets the "decimal" flag that is set by default. This format flag tells iostreams to expect a decimal integer. If it is not set, iostreams expect the integer in any base.

Upvotes: 0

faisal
faisal

Reputation: 1339

This is prints the number after deleting the hex prefix, otherwise return 0:

#include<iostream>
#include<cmath>
#include<stdlib.h>
using namespace std;
int main(){
        string number = "";
        cin >> number;
        string prefix = "dec";
        char zero = '0';
        char hex_prefix = 'x';
        string temp = "";
        int value = 0;
        if (number.size()>=2 && number[0] == zero && number[1] == hex_prefix ) //is hex
        {
            prefix = "hex";
            for(int i = 0; i < (number.size() - 2); ++i)
            {
                temp[i] = number[i+2];

            }

            value = atoi(temp.c_str());
         }
         cout<<value;
        return 0;
}

Upvotes: 0

KhaledMohamedP
KhaledMohamedP

Reputation: 5532

You have two inner loop with same value integer this could be a conflict problem in your code. I suggest you look at the isdigit and islower methods in the c++ library and take advantage of those methods to accomplish your task. isdigit & islower

Good Luck

Upvotes: 0

unwind
unwind

Reputation: 399803

You are checking number[0] twice, that's the first most obvious problem.

The inner if already checks both number[0] and number[1], I don't see the point of the outer one.

The outermost loop is also hard to understand, do you expect non-hex data before the number, or what? Your question could be clearer on how the expected input string looks.

I think the cleanest would be to ignore this, and push it into existing (library) code that can parse integers in any base. In C I would recommend strtoul(), you can of course use that in C++ too.

Upvotes: 2

Related Questions