如何截断字符串 [格式化]? C++

7
我想在cout中截断一个字符串。
string word = "Very long word";
int i = 1;
cout << word << " " << i;

我希望将字符串输出的最大长度限制为8个字母。
因此,在我的情况下,我希望有:
Very lon 1

代替:

Very long word 1

我不想使用wget(8)函数,因为它不会按照我的要求截断单词。同时,我也不希望'word'字符串的值发生改变(我只想向用户展示单词的一部分,但保持变量中的完整单词)。


wget 函数是一个在编程中常用的函数。 - Christian Ternus
我相信你的意思是setw()而不是wget(),对吗? - Dweeberly
2个回答

4

我知道你已经有了解决方案,但我认为这值得一提:你可以简单地使用string::substr,但使用省略号表示字符串已被截断是一种常见的做法。

如果你想要加入这个功能,你只需编写一个简单的截断函数即可。

#include <iostream>
#include <string>

std::string truncate(std::string str, size_t width, bool show_ellipsis=true)
{
    if (str.length() > width)
        if (show_ellipsis)
            return str.substr(0, width) + "...";
        else
            return str.substr(0, width);
    return str;
}

int main()
{
    std::string str = "Very long string";
    int i = 1;
    std::cout << truncate(str, 8) << "\t" << i << std::endl;
    std::cout << truncate(str, 8, false) << "\t" << i << std::endl;
    return 0;
}

输出结果将是:
Very lon...   1
Very lon      1

4
我觉得省略号的例子应该有一个“宽度-3”,否则你的截断结果会超出宽度。 - Paul Beckingham
还需要注意的是,在定义show_ellipsis的默认值时(当在头文件/源文件中定义时),源文件应该只有bool show_ellipsis,而不包含默认值。 - NeoH4x0r

1

正如Chris Olden上面提到的,使用string::substr是截断字符串的一种方法。然而,如果你需要另一种方法来实现这个功能,你可以简单地使用string::resize,然后在字符串被截断时添加省略号。

你可能会想知道string::resize是什么?实际上,它只是调整你的字符串使用的内存(而不是保留的内存),并删除新大小之外的任何字符,只保留你的字符串的前n个字符,其中n是新大小。此外,如果新大小更大,它将扩展你的字符串使用的内存,但我认为这方面的扩展很直观。

当然,我不想建议一个“新的最佳方法”来做到这一点,这只是截断std::string的另一种方式。

如果你改编Chris Olden的截断函数,你会得到这样的结果:

#include <iostream>
#include <string>

std::string& truncate(std::string& str, size_t width, bool show_ellipsis=true) {
    if (str.length() > width) {
        if (show_ellipsis) {
            str.resize(width);
            return str.append("...");
        }
        else {
            str.resize(width);
            return str;
       }
    }
    return str;
}

int main() {
    std::string str = "Very long string";
    int i = 1;
    std::cout << truncate(str, 8) << "\t" << i << std::endl;
    std::cout << truncate(str, 8, false) << "\t" << i << std::endl;
    return 0;
}

尽管这种方法基本上是相同的,但请注意,此方法接受并返回对修改后字符串的引用,因此请小心使用,因为由于代码中的外部事件可能会破坏此字符串。因此,如果您不想冒这个风险,只需删除引用,函数就变成了:
std::string truncate(std::string str, size_t width, bool show_ellipsis=true) {
    if (str.length() > width) {
        if (show_ellipsis) {
            str.resize(width);
            return str + "...";
        }
        else {
            str.resize(width);
            return str;
        }
    }
    return str;
}

我知道现在回答有点晚了,但是对于未来的访问者可能会有所帮助。


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