Reputation: 18350
When you have non-fixed width characters (such as \t
) in a string , or escape codes, such as those for ANSI color (such as \1xb[31m
), these characters add to the .length()
of an std::string
, but do not add to the displayed length when printed.
Is there any way in C++ to get the displayed width of a string in *nix?
For instance:
displayed_width("a\tb") would be 4 if the displayed tab width is 2
displayed_width("\1xb[33mGREEN") would be 5
Upvotes: 7
Views: 1888
Reputation: 1053
Most commonly, a tab asks the terminal program to move the cursor to a column that's a multiple of 8, though many terminal programs let you configure that. With such behaviour, how much width a tab actually adds depends on where the cursor was beforehand relative to the tab stops. So, simply knowing the string content is not enough to calculate a printable width without some assumption or insight regarding prior cursor placement and tab stops.
Non-printable codes also vary per terminal type, though if you only need ANSI colour then that's pretty easy. You can move along the string counting characters; when you see an ESCAPE skip through to the terminating m
. Something like (untested):
int displayed_width(const char* p)
{
int result = 0;
for ( ; *p; ++p)
{
if (p[0] == '\e' && p[1] == '[')
while (*p != 'm')
if (*p)
++p;
else
throw std::runtime_error("string terminates inside ANSI colour sequence");
else
++result;
}
return result;
}
Upvotes: 3
Reputation: 33116
Display length on what device? A console that uses a fixed-width font? A window that uses a proportional font? This is highly device-dependent question. There is no fixed answer. You will have to use the tools associated with the target output device.
Upvotes: 0
Reputation:
Not with standard methods to my knowledge. C++ does not know about terminals. My guess would be to use NCURSES for that. Dunno if boost has something up the sleeve for that though.
Upvotes: 0
Reputation: 43472
Nothing built in. The "displayed width" of the tab character is an implementation detail, as are console escape sequences. C++ doesn't care about platform-specific things like that.
Is there something in particular you're trying to do? We may be able to suggest alternatives if we know what particular task you're working on.
Upvotes: 1