zero padded string from int

Nov 1, 2009 at 6:56pm
Hi all,

Trying to add zeros (eg: "000000") to the left of an integer (converted to string).

I am very new to C++.

I am a VB/WinAPI programmer (16yrs) with some experience writing C style scripts via a proprietary software's exposed APIs. As such, I was pretty isolated to what I could do. Now that I am trying to get into C++, I have been reading books, trying to code myself, and even hired a tutor on Saturdays. Sadly, I am just in the beginning stages.

While trying to create a simple routine today, I am left scratching my head becauase my app keeps crashing.

BTW: I am trying not to rely in the "windows.h" header to keep things as platform independent as possible.


VERY SIMPLE CONCEPT:

1. Create a loop that iterates an integer from 1 to 1000.
2. I try calling a simple function called "ZeroPadNumber" with the intention of returning a string that looks something like this "0001234" (7 character string padded to the left with zeros).
3. In my "main.cpp" I have prototyped my function and the loop works just fine.
4. Everything goes south once I call the above noted function.
5. NOTE: I have hard coded the size of my char arrays because attempts otherwise have failed. This code has undergone so many mutations that I have given up.


HERE IS MY CODE:

void ZeroPadNumber(int num)
{

char* output = new char[6];
char* padded = new char[12];
char* tmp;

for(int i = 0; i < 12; i++)
padded[i] = '0';
padded[12] = '\0';

itoa(num, output, 10);

//strcpy(tmp, padded);
//strcat(tmp, output);

std::cout << "padded: " << padded << endl;


}




NOTE: I do realize that my variable "padded" is being called in the std::cout call as opposed to tmp. Like I said, I've mucked about with this function until I am blue in the face. I was successful at getting just an "itoa" to work all by itself. The moment I do otherwise, kapoof!!
Last edited on Nov 1, 2009 at 7:12pm
Nov 1, 2009 at 7:26pm
Your solution uses standard C instructions.

I wrote my codes in C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <sstream>
using namespace std;

string ZeroPadNumber(int num)
{
	stringstream ss;
	
	// the number is converted to string with the help of stringstream
	ss << num; 
	string ret;
	ss >> ret;
	
	// Append zero chars
	int str_length = ret.length();
	for (int i = 0; i < 7 - str_length; i++)
		ret = "0" + ret;
	return ret;
}


If you need array of chars then you can use the c_str() of the string class.
Last edited on Nov 1, 2009 at 7:28pm
Nov 1, 2009 at 8:07pm
It is GPFing because your tmp pointer is not initialized -- so it points to some random memory location. Make sure you always initialize pointer variables.

Your function does more than it says it does. (It writes to cout.)
You have a memory leak: you allocate two new arrays but you never delete them.
Also, your variable names stink...

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
void CoutZeroPaddedNumber(int num)
{
    char* unpadded   = new char[12];  // What if 'num' were 2147483647?
                                      // (11+1 is sufficient for any 32-bit int value)
    char* padded     = new char[8];   // This time, you know you only need 7+1 characters.
    char* unpadbegin = NULL;          // This is a good habit -- initialize pointers to NULL.
    int   unpadlength;

    // Convert the argument number to a string
    itoa(num,unpadded,10);

    // Now we want the last 7 digits of the input number
    // (For simplicity, we'll just ignore extra digits)
    unpadlength = strlen(unpadded);

    if (unpadlength > 7)
    {
        unpadbegin = unpadded + unpadlength - 7;
        unpadlength = 7;
    }
    else
    {
        unpadbegin = unpadded;
    }

    // Now, fill the beginning of the padded string with zeroes
    memset((void*)padded, '0', 7 - unpadlength);
    // Don't forget to terminate the string
    padded[7 - unpadlength] = '\0';

    // Now append the converted number
    strcat(padded,unpadbegin);

    // Finally, we can write it to cout
    std::cout << "padded: " << padded << std::endl;

    // Free heap memory we used
    delete [] padded;
    delete [] unpadded;
}


That is all overkill for C++ though. Why not use the standard streams to do it for you?
1
2
3
#include <iomanip>
#include <sstream>
#include <string> 
1
2
3
4
5
6
std::string ZeroPadNumber(int num)
{
    std::ostringstream ss;
    ss << std::setw( 7 ) << std::setfill( '0' ) << num;
    return ss.str();
}
1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;

int main()
{
    cout << "7 padded: " << ZeroPadNumber(7) << endl;
    cout << "2147483647 padded: " << ZeroPadNumber(2147483647) << endl;
}

You'll notice that last example permits output greater than seven digits. You can restrict that easily enough:
1
2
3
4
5
6
7
8
9
10
11
std::string ZeroPadNumber(int num)
{
    std::ostringstream ss;
    ss << std::setw(7) << std::setfill('0') << num;
    std::string result = ss.str();
    if (result.length() > 7)
    {
        result.erase(0, result.length() - 7);
    }
    return result;
}

Hope this helps.
Nov 1, 2009 at 9:34pm
Thanks very much!! This worked perfectly.

I guess I am going to have to spend some time learning the new libraries offered by C++.

Thanks again!
Topic archived. No new replies allowed.