Format integer as a string

Hello. Is there a way to format an integer according its memory size using to_string?
I explain my will by an example :

1
2
3
4
5
6
std::string message = "my message";
gck::Pixel selectedPixel = gck::BLACK;
(...)
message = "r:" + std::to_string(uint8_t(selectedPixel.r));
message += " g:" + std::to_string(uint8_t(selectedPixel.g));
message += " b:" + std::to_string(uint8_t(selectedPixel.b));


Clicking on my previous color spectrum, this code gives me each value for a selected pixel. As you can see, RGB values are UINT_8. So value is at least 0 and the maximum is 255. Actually this code writes values this way :

R: 128 G: 64 B: 222 or R: 11 G: 177 B: 88...

However, I would like something like that :
R: 128 G: 064 B: 222 or R: 011 G: 177 B: 088...

Do you have an idea? Thank you ++
Last edited on
std::to_string doesn't offer formatting options. However, there are ways of formatting output:
* sprintf // all C implementations
* iostream library // all C++ implementations
* std::format // c++20
* fmt::format // pre c++20, https://github.com/fmtlib/fmt
Last edited on
Hum. I said to myself that there are some limitations using to_string which is useful, but not really efficient. Thank you for your tips. I will change this part of my code ++
If you're using VS, then you could use std::format (C++20 feature currently only implemented in VS). eg

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <format>

int main() {
	uint8_t r{11}, g{177}, b{88};

	std::string message { std::format("r:{:03d} g:{:03d} b:{:03d}", r, g, b) };

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


Or using a ostringstream then:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <sstream>
#include <iomanip>

int main() {
	uint8_t r{11}, g{177}, b{88};

	std::ostringstream message;
	message << "r:" << std::setw(3) << std::setfill('0') << (int)r <<
		" g:" << std::setw(3) << std::setfill('0') << (int)g <<
		" b: " << std::setw(3) << std::setfill('0') << (int)b;

	std::cout << message.str() << '\n';
}


or using snprintf:

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

using namespace std::string_literals;

int main() {
	uint8_t r{11}, g{177}, b{88};
	char num[20] {};
	std::string message { "r:" };

	snprintf(num, sizeof(num), "%03d", r);
	message += num + " g:"s;
	snprintf(num, sizeof(num), "%03d", g);
	message += num + " b:"s;
	snprintf(num, sizeof(num), "%03d", b);
	message += num;

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


or just use a char array:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <sstream>
#include <iomanip>

int main() {
	uint8_t r{11}, g{177}, b{88};
	char message[100] {};

	snprintf(message, sizeof(message), "r:%03d g:%03d b:%03d", r, g, b);

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




r:011 g:177 b:088

Last edited on
PS Note that in c/c++, a literal number starting with a 0 is interpreted as being octal!

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <sstream>
#include <iomanip>

int main() {
	uint8_t r{011}, g{177}, b{077};
	char message[100] {};

	snprintf(message, sizeof(message), "r:%03d g:%03d b:%03d", r, g, b);

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


displays:


r:009 g:177 b:063


as the numbers on L6 starting with 0 are interpreted as octal!
Last edited on
> in c/c++, a number starting with a 0 is interpreted as being octal!

This is only for literals (tokens embedded in source code that represent constant values).

Otherwise, there is no such convention; for instance, the hh:mm:ss values here are decimal 09:09:09:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <ctime>


int main()
{
    std::tm tm {} ;
    tm.tm_hour = tm.tm_min = tm.tm_sec = 9 ;
    tm.tm_mday = tm.tm_mon = 11 ;
    tm.tm_year = 122 ;
    std::cout << std::asctime( std::addressof( tm ) ) ; // Sun Dec 11 09:09:09 2022

    int n = 0 ;
    std::cin >> n ; // enter 01234
    std::cout << "decimal: " << n << "  octal: " << std::oct << n << '\n' ; // decimal: 1234  octal: 2322
}

http://coliru.stacked-crooked.com/a/618cb84619ab96c7
Yes, I was loose with my wording. I meant a literal number. In the code above if L9 was 011 then this would be an octal number.

I mentioned this because an output of say:

r:005 g:012 b:020

could be thought of these being octal numbers. I'm not a fan in cases like this being left 0 filled (except in cases like time etc).
Now the message is simply concatenated this way :
 
snprintf(message, sizeof(message), "r:%03d g:%03d b:%03d", selectedPixel.r, selectedPixel.g, selectedPixel.b);

Thank you for your help and your explanations ++
Last edited on
Topic archived. No new replies allowed.