Jamie Wong
Jamie Wong

Reputation: 18350

How to get displayed width of a string?

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

Answers (4)

user433534
user433534

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

David Hammen
David Hammen

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

user852830
user852830

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

Jonathan Grynspan
Jonathan Grynspan

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

Related Questions