在C++中填充stl字符串

76

我正在使用 std::string,需要将它们左侧填充到给定的宽度。在 C++ 中推荐使用什么方法来完成这个任务?

示例输入:

123

填充至10个字符。

示例输出:

       123

(123 前有 7 个空格)

14个回答

87

std::setw(设置宽度)操作符

std::cout << std::setw (10) << 77 << std::endl;
或者
std::cout << std::setw (10) << "hi!" << std::endl;

输出结果为 77 和 "hi!",其中 77 是经过填充的。

如果您需要字符串形式的结果,请使用 std::stringstream 实例代替 std::cout 对象。

PS:请确保包含头文件 <iomanip>


很棒的回答。有没有可能以最小工作示例的形式呈现?谢谢。 - puk
2
对于一个简单的 std::to_string(n),使用 stringstream 似乎有很多开销... - ebyrob

55
void padTo(std::string &str, const size_t num, const char paddingChar = ' ')
{
    if(num > str.size())
        str.insert(0, num - str.size(), paddingChar);
}

int main(int argc, char **argv)
{
    std::string str = "abcd";
    padTo(str, 10);
    return 0;
}

我喜欢这个解决方案,因为在各种Linux操作系统中,字符串流需要一个GLIBC依赖项,而该依赖项不可用。 - Wylie Coyote SG.
5
插入(insert)字符时使用insert(0,...)是不好的想法,因为它很慢,每次插入一个新字符都需要复制字符串。 - arhuaco
@arhuaco 为什么 std::string::insert() 会复制一份呢?它是在原地操作缓冲区的。这可不是 Java/C#。如果你想要糟糕的性能,那就选择任何使用流的解决方案吧... - ebyrob
@ebyrob 我误读了代码。它相当不错。顺便说一下,在 LeftPad 事件之后,我实现了 一些代码 作为一个玩笑,它非常相似(就是原地版本)。 - arhuaco

32

你可以像这样使用它:

std::string s = "123";
s.insert(s.begin(), paddedLength - s.size(), ' ');

22

我能想到的最简单的方法是使用stringstream:

string foo = "foo";
stringstream ss;
ss << setw(10) << foo;
foo = ss.str();

现在应该对foo进行填充。


15
std::string pad_right(std::string const& str, size_t s)
{
    if ( str.size() < s )
        return str + std::string(s-str.size(), ' ');
    else
        return str;
}

std::string pad_left(std::string const& str, size_t s)
{
    if ( str.size() < s )
        return std::string(s-str.size(), ' ') + str;
    else
        return str;
}

1
最佳答案 - 除了那可怕的大括号缺失之外。 :) - Andrew
@Andrew 至少我的编译器不会接受初始化列表中的长度和字符。我需要明确指定要使用的构造函数,就像Francois的回答中那样。 - Smartskaft2
@Smartskaft2 我相信我的评论是关于分支的。 - Andrew

12

你可以通过调用函数来创建一个包含 N 个空格的字符串

string(N, ' ');

这样您可以像这样实现:

string to_be_padded = ...;
if (to_be_padded.size() < 10) {
  string padded(10 - to_be_padded.size(), ' ');
  padded += to_be_padded;
  return padded;
} else { return to_be_padded; }

最佳答案,但格式混乱,难以阅读。 - Paul

3
有一个简单易行的方法 :)
const int required_pad = 10;

std::string myString = "123";
size_t length = myString.length();

if (length < required_pad)
  myString.insert(0, required_pad - length, ' ');

1

请在https://repl.it/@JomaCorpFX/Padding#main.cpp上测试此代码。

我们有两种填充类型

  • 普通填充

它将字符串的每个字符作为单独的元素。

std::string str = u8"Hello"; //5 elements
std::string str2 = u8"Hello "; //10 elements //  has 4 chars.
std::string str3 = u8""; //4 elements //  has 4 chars.
  • UTF8填充

它以UTF8单位长度为参数,一个UTF8单位可以是1-4个字符。

std::string str = u8"Hello"; //5 UTF8 units.
std::string str2 = u8"Hello "; //7 UTF8 units //  is an individual element.
std::string str3 = u8""; //1 UTF8 units

这些函数

class Strings
{

    static size_t LengthUTF8(const String& data);

    static String SubstringUTF8(const String& data, size_t startIndex, size_t length);

    static String PadRight(const String& data, const size_t& totalWidth, const char& padding);

    static String PadLeft(const String& data, const size_t& totalWidth, const char& padding);

    static String PadRight(const String& data, const size_t& totalWidth, const String& padding);

    static String PadLeft(const String& data, const size_t& totalWidth, const String& padding);

    static String PadRightUTF8(const String& data, const size_t& totalWidth, const char& padding);

    static String PadLeftUTF8(const String& data, const size_t& totalWidth, const char& padding);

    static String PadRightUTF8(const String& data, const size_t& totalWidth, const String& padding);

    static String PadLeftUTF8(const String& data, const size_t& totalWidth, const String& padding);
};

以UTF8结尾的函数会将字符串视为UTF8单位来确定其长度。不以UTF8结尾的函数将每个字符视为一个单位来确定长度。

如果填充是一个字符串,且它是一个UTF8函数,它将被视为UTF8单位;否则将视为字符。

参数totalWidth基于函数是否使用normal或UTF8。

FULLCODE


#include <iostream>
#include <set>
#include <string>
#include <locale>

// WINDOWS
#if (_WIN32)
#include <Windows.h>
#include <conio.h>
#define WINDOWS_PLATFORM 1
#define DLLCALL STDCALL
#define DLLIMPORT _declspec(dllimport)
#define DLLEXPORT _declspec(dllexport)
#define DLLPRIVATE
#define NOMINMAX

//EMSCRIPTEN
#elif defined(__EMSCRIPTEN__)
#include <emscripten/emscripten.h>
#include <emscripten/bind.h>
#include <unistd.h>
#include <termios.h>
#define EMSCRIPTEN_PLATFORM 1
#define DLLCALL
#define DLLIMPORT
#define DLLEXPORT __attribute__((visibility("default")))
#define DLLPRIVATE __attribute__((visibility("hidden")))

// LINUX - Ubuntu, Fedora, , Centos, Debian, RedHat
#elif (__LINUX__ || __gnu_linux__ || __linux__ || __linux || linux)
#define LINUX_PLATFORM 1
#include <unistd.h>
#include <termios.h>
#define DLLCALL CDECL
#define DLLIMPORT
#define DLLEXPORT __attribute__((visibility("default")))
#define DLLPRIVATE __attribute__((visibility("hidden")))
#define CoTaskMemAlloc(p) malloc(p)
#define CoTaskMemFree(p) free(p)

//ANDROID
#elif (__ANDROID__ || ANDROID)
#define ANDROID_PLATFORM 1
#define DLLCALL
#define DLLIMPORT
#define DLLEXPORT __attribute__((visibility("default")))
#define DLLPRIVATE __attribute__((visibility("hidden")))

//MACOS
#elif defined(__APPLE__)
#include <unistd.h>
#include <termios.h>
#define DLLCALL
#define DLLIMPORT
#define DLLEXPORT __attribute__((visibility("default")))
#define DLLPRIVATE __attribute__((visibility("hidden")))
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE && TARGET_IPHONE_SIMULATOR
#define IOS_SIMULATOR_PLATFORM 1
#elif TARGET_OS_IPHONE
#define IOS_PLATFORM 1
#elif TARGET_OS_MAC
#define MACOS_PLATFORM 1
#else

#endif

#endif



typedef std::string String;
typedef std::wstring WString;

#define EMPTY_STRING u8""s
#define EMPTY_WSTRING L""s

using namespace std::literals::string_literals;

class Strings
{
public:
    static String WideStringToString(const WString& wstr)
    {
        if (wstr.empty())
        {
            return String();
        }
        size_t pos;
        size_t begin = 0;
        String ret;

#if WINDOWS_PLATFORM
        int size;
        pos = wstr.find(static_cast<wchar_t>(0), begin);
        while (pos != WString::npos && begin < wstr.length())
        {
            WString segment = WString(&wstr[begin], pos - begin);
            size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), NULL, 0, NULL, NULL);
            String converted = String(size, 0);
            WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), &converted[0], converted.size(), NULL, NULL);
            ret.append(converted);
            ret.append({ 0 });
            begin = pos + 1;
            pos = wstr.find(static_cast<wchar_t>(0), begin);
        }
        if (begin <= wstr.length())
        {
            WString segment = WString(&wstr[begin], wstr.length() - begin);
            size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), NULL, 0, NULL, NULL);
            String converted = String(size, 0);
            WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), &converted[0], converted.size(), NULL, NULL);
            ret.append(converted);
        }
#elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
        size_t size;
        pos = wstr.find(static_cast<wchar_t>(0), begin);
        while (pos != WString::npos && begin < wstr.length())
        {
            WString segment = WString(&wstr[begin], pos - begin);
            size = wcstombs(nullptr, segment.c_str(), 0);
            String converted = String(size, 0);
            wcstombs(&converted[0], segment.c_str(), converted.size());
            ret.append(converted);
            ret.append({ 0 });
            begin = pos + 1;
            pos = wstr.find(static_cast<wchar_t>(0), begin);
        }
        if (begin <= wstr.length())
        {
            WString segment = WString(&wstr[begin], wstr.length() - begin);
            size = wcstombs(nullptr, segment.c_str(), 0);
            String converted = String(size, 0);
            wcstombs(&converted[0], segment.c_str(), converted.size());
            ret.append(converted);
        }
#else
        static_assert(false, "Unknown Platform");
#endif
        return ret;
    }

    static WString StringToWideString(const String& str)
    {
        if (str.empty())
        {
            return WString();
        }

        size_t pos;
        size_t begin = 0;
        WString ret;
#ifdef WINDOWS_PLATFORM
        int size = 0;
        pos = str.find(static_cast<char>(0), begin);
        while (pos != std::string::npos) {
            std::string segment = std::string(&str[begin], pos - begin);
            std::wstring converted = std::wstring(segment.size() + 1, 0);
            size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, &segment[0], segment.size(), &converted[0], converted.length());
            converted.resize(size);
            ret.append(converted);
            ret.append({ 0 });
            begin = pos + 1;
            pos = str.find(static_cast<char>(0), begin);
        }
        if (begin < str.length()) {
            std::string segment = std::string(&str[begin], str.length() - begin);
            std::wstring converted = std::wstring(segment.size() + 1, 0);
            size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, segment.c_str(), segment.size(), &converted[0], converted.length());
            converted.resize(size);
            ret.append(converted);
        }

#elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
        size_t size;
        pos = str.find(static_cast<char>(0), begin);
        while (pos != String::npos)
        {
            String segment = String(&str[begin], pos - begin);
            WString converted = WString(segment.size(), 0);
            size = mbstowcs(&converted[0], &segment[0], converted.size());
            converted.resize(size);
            ret.append(converted);
            ret.append({ 0 });
            begin = pos + 1;
            pos = str.find(static_cast<char>(0), begin);
        }
        if (begin < str.length())
        {
            String segment = String(&str[begin], str.length() - begin);
            WString converted = WString(segment.size(), 0);
            size = mbstowcs(&converted[0], &segment[0], converted.size());
            converted.resize(size);
            ret.append(converted);
        }
#else
        static_assert(false, "Unknown Platform");
#endif
        return ret;
    }

    static size_t LengthUTF8(const String& data)
    {
        size_t ret = 0;
        for (char value : data)
        {
            if ((value & 0xc0) != 0x80)
            {
                ++ret;
            }
        }
        return ret;
    }

    static String SubstringUTF8(const String& data, size_t startIndex, size_t length)
    {
        size_t units = LengthUTF8(data);
        if (startIndex >= units)
        {
            throw std::invalid_argument(u8"Invalid UTF8 character position.");
        }
        String result;
        String::const_iterator it = data.begin();
        String::const_iterator beginIterator = data.begin();
        size_t endIndex = length == SIZE_MAX ? units : startIndex + length;
        size_t utf8pos = 0;
        while (it != data.end())
        {
            char value = *it;
            if ((value & 0xc0) != 0x80) // Es inicio de caracter //utf8pos = 0 / beginIterator = 0 / endIndex = 1+12
            {
                if (utf8pos == startIndex)
                {
                    beginIterator = it;
                    if (length >= units)
                    {
                        return String(beginIterator, data.end());
                    }
                }

                if (utf8pos == endIndex)
                {
                    break;
                }
                utf8pos += 1;
            }
            it++;
        }
        return String(beginIterator, it);
    }

    static String GetCharUTF8(const String& data, size_t pos)
    {
        return SubstringUTF8(data, pos, 1);
    }

    static String PadRight(const String& data, const size_t& totalWidth, const char& padding)
    {
        if (data.length() >= totalWidth)
        {
            return data;
        }
        String ret = data;
        ret.resize(totalWidth, padding);
        return ret;
    }

    static String PadLeft(const String& data, const size_t& totalWidth, const char& padding)
    {
        if (data.length() >= totalWidth)
        {
            return data;
        }
        String ret = data;
        ret.insert(0, totalWidth - ret.length(), padding);
        return ret;
    }

    static String PadRight(const String& data, const size_t& totalWidth, const String& padding)
    {

        if (data.length() >= totalWidth)
        {
            return data;
        }
        size_t modulo = (totalWidth - data.length()) % padding.length();
        size_t paddingUnits = (totalWidth - data.length()) / padding.length();
        String ret = data;
        for (size_t i = 0; i < paddingUnits; i++)
        {
            ret.append(padding);
        }
        ret.append(padding.substr(0, modulo));
        return ret;
    }

    static String PadLeft(const String& data, const size_t& totalWidth, const String& padding)
    {
        if (data.length() >= totalWidth)
        {
            return data;
        }
        size_t modulo = (totalWidth - data.length()) % padding.length();
        size_t paddingUnits = (totalWidth - data.length()) / padding.length();
        String ret = data;
        for (size_t i = 0; i < paddingUnits; i++)
        {
            ret.insert(0, padding);
        }
        ret.insert(0, padding.substr(0, modulo));
        return ret;
    }

    static String PadRightUTF8(const String& data, const size_t& totalWidth, const char& padding)
    {
        size_t totalUtf8 = LengthUTF8(data);
        if (totalUtf8 >= totalWidth)
        {
            return data;
        }
        String ret = data;
        ret.resize(ret.length() + (totalWidth - totalUtf8), padding);
        return ret;
    }

    static String PadLeftUTF8(const String& data, const size_t& totalWidth, const char& padding)
    {
        size_t totalUtf8 = LengthUTF8(data);
        if (totalUtf8 >= totalWidth)
        {
            return data;
        }
        String ret = data;
        ret.insert(0, totalWidth - totalUtf8, padding);
        return ret;
    }

    static String PadRightUTF8(const String& data, const size_t& totalWidth, const String& padding)
    {
        size_t units = LengthUTF8(data);
        size_t paddingUnits = LengthUTF8(padding);
        if (units >= totalWidth)
        {
            return data;
        }
        size_t modulo = (totalWidth - units) % paddingUnits;
        size_t n = (totalWidth - units) / paddingUnits;
        String ret = data;
        for (size_t i = 0; i < n; i++)
        {
            ret.append(padding);
        }
        ret.append(SubstringUTF8(padding, 0, modulo));
        return ret;
    }

    static String PadLeftUTF8(const String& data, const size_t& totalWidth, const String& padding)
    {
        size_t units = LengthUTF8(data);
        size_t paddingUnits = LengthUTF8(padding);
        if (units >= totalWidth)
        {
            return data;
        }
        size_t modulo = (totalWidth - units) % paddingUnits;
        size_t n = (totalWidth - units) / paddingUnits;
        String ret = data;
        for (size_t i = 0; i < n; i++)
        {
            ret.insert(0, padding);
        }
        ret.insert(0, SubstringUTF8(padding, 0, modulo));
        return ret;
    }


};

enum class ConsoleTextStyle
{
    DEFAULT = 0,
    BOLD = 1,
    FAINT = 2,
    ITALIC = 3,
    UNDERLINE = 4,
    SLOW_BLINK = 5,
    RAPID_BLINK = 6,
    REVERSE = 7,
};

enum class ConsoleForeground
{
    DEFAULT = 39,
    BLACK = 30,
    DARK_RED = 31,
    DARK_GREEN = 32,
    DARK_YELLOW = 33,
    DARK_BLUE = 34,
    DARK_MAGENTA = 35,
    DARK_CYAN = 36,
    GRAY = 37,
    DARK_GRAY = 90,
    RED = 91,
    GREEN = 92,
    YELLOW = 93,
    BLUE = 94,
    MAGENTA = 95,
    CYAN = 96,
    WHITE = 97
};

enum class ConsoleBackground
{
    DEFAULT = 49,
    BLACK = 40,
    DARK_RED = 41,
    DARK_GREEN = 42,
    DARK_YELLOW = 43,
    DARK_BLUE = 44,
    DARK_MAGENTA = 45,
    DARK_CYAN = 46,
    GRAY = 47,
    DARK_GRAY = 100,
    RED = 101,
    GREEN = 102,
    YELLOW = 103,
    BLUE = 104,
    MAGENTA = 105,
    CYAN = 106,
    WHITE = 107
};

class Console //For Printing Unicode strings.
{
private:
    static void EnableVirtualTermimalProcessing()
    {
#if defined WINDOWS_PLATFORM
        HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
        DWORD dwMode = 0;
        GetConsoleMode(hOut, &dwMode);
        if (!(dwMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING))
        {
            dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
            SetConsoleMode(hOut, dwMode);
        }
#endif
    }

    static void ResetTerminalFormat()
    {
        std::cout << u8"\033[0m";
    }

    static void SetVirtualTerminalFormat(ConsoleForeground foreground, ConsoleBackground background, std::set<ConsoleTextStyle> styles)
    {
        String format = u8"\033[";
        format.append(std::to_string(static_cast<int>(foreground)));
        format.append(u8";");
        format.append(std::to_string(static_cast<int>(background)));
        if (styles.size() > 0)
        {
            for (auto it = styles.begin(); it != styles.end(); ++it)
            {
                format.append(u8";");
                format.append(std::to_string(static_cast<int>(*it)));
            }
        }
        format.append(u8"m");
        std::cout << format;
    }
public:
    static void Clear()
    {

#ifdef WINDOWS_PLATFORM
        std::system(u8"cls");
#elif LINUX_PLATFORM || defined MACOS_PLATFORM
        std::system(u8"clear");
#elif EMSCRIPTEN_PLATFORM
        emscripten::val::global()["console"].call<void>(u8"clear");
#else
        static_assert(false, "Unknown Platform");
#endif
    }

    static void Write(const String& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
    {
#ifndef EMSCRIPTEN_PLATFORM
        EnableVirtualTermimalProcessing();
        SetVirtualTerminalFormat(foreground, background, styles);
#endif
        String str = s;
#ifdef WINDOWS_PLATFORM
        WString unicode = Strings::StringToWideString(str);
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), unicode.c_str(), static_cast<DWORD>(unicode.length()), nullptr, nullptr);
#elif defined LINUX_PLATFORM || defined MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
        std::cout << str;
#else
        static_assert(false, "Unknown Platform");
#endif

#ifndef EMSCRIPTEN_PLATFORM
        ResetTerminalFormat();
#endif
    }

    static void WriteLine(const String& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
    {
        Write(s, foreground, background, styles);
        std::cout << std::endl;
    }

    static void Write(const WString& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
    {
#ifndef EMSCRIPTEN_PLATFORM
        EnableVirtualTermimalProcessing();
        SetVirtualTerminalFormat(foreground, background, styles);
#endif
        WString str = s;

#ifdef WINDOWS_PLATFORM
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), str.c_str(), static_cast<DWORD>(str.length()), nullptr, nullptr);
#elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
        std::cout << Strings::WideStringToString(str);
#else
        static_assert(false, "Unknown Platform");
#endif

#ifndef EMSCRIPTEN_PLATFORM
        ResetTerminalFormat();
#endif
    }

    static void WriteLine(const WString& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
    {
        Write(s, foreground, background, styles);
        std::cout << std::endl;
    }

    static void WriteLine()
    {
        std::cout << std::endl;
    }

    static void Pause()
    {
        char c;
        do
        {
            c = getchar();
            std::cout << "Press Key " << std::endl;
        } while (c != 64);
        std::cout << "KeyPressed" << std::endl;
    }

    static int PauseAny(bool printWhenPressed = false, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
    {
        int ch;
#ifdef WINDOWS_PLATFORM
        ch = _getch();
#elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
        struct termios oldt, newt;
        tcgetattr(STDIN_FILENO, &oldt);
        newt = oldt;
        newt.c_lflag &= ~(ICANON | ECHO);
        tcsetattr(STDIN_FILENO, TCSANOW, &newt);
        ch = getchar();
        tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
#else
        static_assert(false, "Unknown Platform");
#endif
        if (printWhenPressed)
        {
            Console::Write(String(1, ch), foreground, background, styles);
        }
        return ch;
    }
};



int main()
{

    //u8"" 4 char units

    char charPadding = u8'@';
    std::string stringPadding = u8"<>"s;
    std::string unicodeStringPadding = u8""s;
    
    std::locale::global(std::locale(u8"en_US.UTF8"));

    //No UTF8 examples
    String str = u8"Hello "s;
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadLeft(str, 10, charPadding) + u8" █ PadLeft with char padding");//"Hello " No changes. Length 10 == totalWith 10
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadLeft(str, 15, charPadding) + u8" █ PadLeft with char padding");//"@@@@@Hello "

    str = u8"Hello "s;
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadRight(str, 10, charPadding) + u8" █ PadRight with char padding");//"Hello " No changes. Length 10 == totalWith 10
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadRight(str, 15, charPadding) + u8" █ PadRight with char padding");//"Hello @@@@@"

    str = u8"Hello "s;
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadLeft(str, 10, stringPadding) + u8" █ PadLeft with string padding");//"Hello " No changes. Length 10 == totalWith 10
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadLeft(str, 15, stringPadding) + u8" █ PadLeft with string padding");//"<<><>Hello "

    str = u8"Hello "s;
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadRight(str, 10, stringPadding) + u8" █ PadRight with string padding");//"Hello " No changes. Length 10 == totalWith 10
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadRight(str, 15, stringPadding) + u8" █ PadRight with string padding");//"Hello <><><"

    //UTF8 Examples
    str = u8"Hello "s;
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadLeftUTF8(str, 7, charPadding) + u8" █ PadLeftUTF8 with char padding");//"Hello " No changes. UTF8Length 7 == totalWith 7
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadLeftUTF8(str, 15, charPadding) + u8" █ PadLeftUTF8 with char padding");//"@@@@@@@@Hello "

    str = u8"Hello "s;
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadRightUTF8(str, 7, charPadding) + u8" █ PadRightUTF8 with char padding");//"Hello " No changes. UTF8Length 7 == totalWith 7
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadRightUTF8(str, 15, charPadding) + u8" █ PadRightUTF8 with char padding");//"Hello @@@@@@@@"

    str = u8"Hello "s;
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadLeftUTF8(str, 7, unicodeStringPadding) + u8" █ PadLeftUTF8 with string padding");//"Hello " No changes. UTF8Length 7 == totalWith 7
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadLeftUTF8(str, 15, unicodeStringPadding) + u8" █ PadLeftUTF8 with string padding");//"Hello "

    str = u8"Hello "s;
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadRightUTF8(str, 7, unicodeStringPadding) + u8" █ PadRightUTF8 with string padding");//"Hello " No changes. UTF8Length 7 == totalWith 7
    Console::WriteLine(u8"Original: " + str + u8" █ StrLength: " + std::to_string(str.length()) + u8" █ UTF8Chars: " + std::to_string(Strings::LengthUTF8(str)) + u8" █ Padded:" + Strings::PadRightUTF8(str, 15, unicodeStringPadding) + u8" █ PadRightUTF8 with string padding");//"Hello "

    Console::WriteLine();
    Console::WriteLine(u8"Press any key to exit"s, ConsoleForeground::DARK_GRAY);
    Console::PauseAny();

}

输出

Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello   PadLeft with char padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:@@@@@Hello   PadLeft with char padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello   PadRight with char padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello @@@@@  PadRight with char padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello   PadLeft with string padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:<<><>Hello   PadLeft with string padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello   PadRight with string padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello <><><  PadRight with string padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello   PadLeftUTF8 with char padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:@@@@@@@@Hello   PadLeftUTF8 with char padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello   PadRightUTF8 with char padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello @@@@@@@@  PadRightUTF8 with char padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello   PadLeftUTF8 with string padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello   PadLeftUTF8 with string padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello   PadRightUTF8 with string padding
Original: Hello   StrLength: 10  UTF8Chars: 7  Padded:Hello   PadRightUTF8 with string padding

使用新的Windows Terminal可以绘制Unicode表情符号。使用Visual Studio附带的Microsoft Visual C++编译器+/std:c++17+/utf-8:

Windows Terminal, windows, visual studio, msvc

使用经典的控制台 cmd.exe,绘图效果较差。

cmd, windows, visual studio, msvc

使用Linux + Clang + std=c++17在repl.it中输出https://repl.it/@JomaCorpFX/Padding#main.cpp

Linux, clang


1

这样怎么样:

string s = "          "; // 10 spaces
string n = "123";
n.length() <= 10 ? s.replace(10 - n.length(), n.length(), s) : s = n;

1

最小工作代码:

#include <iostream>
#include <iomanip>

int main()
{
    for(int i = 0; i < 300; i += 11)
    {
        std::cout << std::setfill ( ' ' ) << std::setw (2) << (i % 100) << std::endl;
    }
    return 0;
}

/*
Note:
- for std::setfill ( ' ' ):
  - item in '' is what will be used for filling
- std::cout may be replaced with a std::stringstream if you need it
- modulus is used to cut the integer to an appropriate length, for strings use substring
- std::setw is used to define the length of the needed string
*/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接