Panagiotis
Panagiotis

Reputation: 27

convert a string to integer in c++ without losing leading zeros

hello i have a problem with converting a string of numbers to integer. the problem is that using atoi() to convert the string to integer i loose the leading zeros. can you please tell me a way to do that without loosing the leading zeros?

#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>


using namespace std;

struct Book{
    int id;
    string title;
};

struct Author{
    string firstName; 
    string lastName;
};

Author authorInfo[200];
Book bookInfo[200];

void load ( void )
{

    int count = 0;
    string temp;

    ifstream fin;
    fin.open("myfile.txt");

    if (!fin.is_open())
    {
        cout << "Unable to open myfile.txt file\n";
        exit(1);
    }

    while (fin.good())
    {   
        getline(fin, temp, '#');
        bookInfo[count].id = atoi(temp.c_str());
        getline(fin, bookInfo[count].title, '#');
        getline(fin, authorInfo[count].firstName, '#');
        getline(fin, authorInfo[count].lastName, '#');
        count++;
    }

    fin.close(); 
}

Upvotes: 2

Views: 5853

Answers (7)

You You
You You

Reputation: 31

I have encountered this type of problem last month!

I think you can use the Format() method provided by Class CString: CString::Format() formats and stores a series of characters and values in the CString. Each optional argument (if any) is converted and output according to the corresponding format specification in pszFormat or from the string resource identified by nFormatID. For example:

CString m_NodeName;
m_NodeName.Format(_T("%.4d"),Recv[2]*100+Recv[3]);
// %.4d means the argument will be formatted as an integer, 
// 4 digits wide, with unused digits filled with leading zeroes

For the detail you can find here: http://msdn.microsoft.com/zh-cn/library/18he3sk6(v=vs.100).aspx

Upvotes: 1

AnT stands with Russia
AnT stands with Russia

Reputation: 320391

There's no such thing as "leading zeros" in a number. "Leading zeros" is a property of a specific notation, like decimal ASCII representation of a number. Once you convert that notation to a conceptually abstract numerical representation, such metric as "number of leading zeros" is no longer applicable (at least in decimal terms). It is lost without a trace.

A number is a number. It doesn't have any "zeros", leading or otherwise.

The only thing you can do is to memorize how many leading zeros you had in the original notation (or how wide was the field), and then later, when you will convert the number back to decimal ASCII representation, re-create the proper number of leading zeros using that stored information.

BTW, in your case, when the input number represents a book ID with some pre-determined formatting (like leading zeros), you might consider a different approach: don't convert your book ID to int. Keep it as a string. It is not like you are going to have to perform arithmetic operations on book IDs, is it? Most likely all you'll need is relational and equality comparisons, which can be performed on strings.

Upvotes: 2

Mats Petersson
Mats Petersson

Reputation: 129324

Ok, so I don't think you actually WANT to store the leading zeros. I think you want to DISPLAY a consistent number of digits in the output.

So, for example, to display a fixed size id with 5 digits [note that an id of 100000 will still display in 6 digits - all it does here is make sure it's always at least 5 digits, and fill it with '0' if the number is not big enough], we could do:

std::cout << std::setw(5) << std::setfill('0') << id << ... 

Alternatively, as suggested in other answers, you don't want to use the ID in a form that is an integer, you could just store it as a string - unless you are going to do math on it, all that it changes is that it takes up a tiny bit more memory per book.

Upvotes: 4

paxdiablo
paxdiablo

Reputation: 881243

An integer does not have leading zeroes. Or perhaps, more correctly, it has between zero and an infinite number of them. The numbers 42, 042 and 000000042 (other than in the source code where a leading 0 indicates a different base) are all forty-two.

If you want to keep the leading zeroes, either leave it as a string or store more information somewhere as to how big the original string was. Something like this would be a good start:

#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdio>
#include <cstdlib>

int main (void) {
    // Test data.

    const char *sval = "0042";

    // Get original size.

    int size = strlen (sval);

    // Convert to int (without leading 0s).
    // strtol would be better for detecting bad numbers.

    int ival = atoi (sval);

    // Output details.

    std::cout << sval << " has size of " << size << ".\n";
    std::cout << "Integer value is " << ival << ".\n";
    std::cout << "Recovered value is " << std::setw(size)
        << std::setfill('0') << ival << ".\n";

    return 0;
}

which outputs:

0042 has size of 4.
Integer value is 42.
Recovered value is 0042.

Upvotes: 3

Captain Skyhawk
Captain Skyhawk

Reputation: 3500

There is no way of storing an int with leading 0s.

What you may want to do instead, is have a class do it for you:

 class intWithLeadingZeros {
       int number;
       int numberOfLeadingZeros;

       intWithLeadingZeros( string val )
       {
          // trivial code to break down string into zeros and number
       }

       string toString() {
            // trivial code that concatenates leading 0s and number
       }



 };

Upvotes: 0

Cob013
Cob013

Reputation: 1067

A = strlen(string) returns the number of characters in your string (say number of digits comprehensive of leading zeros)

B = log10(atoi(string)) + 1 returns the number of digits in your number

A - B => number of leading zeros.

Now you can format those as you prefer.

Upvotes: 2

John3136
John3136

Reputation: 29266

If you need the leading zeros, then int is not the correct data type to use. In your case you may be better off just storing the original string.

Upvotes: 0

Related Questions