在使用一些遗留代码的项目中工作时,我发现了这个功能:
std::vector<std::string> Object::getTypes(){
static std::string types [] = {"type1","type2", "type3"};
return std::vector<std::string> (types , types +2);
}
Run Code Online (Sandbox Code Playgroud)
我可能会把它写成:
std::vector<std::string> Object::getTypes(){
std::vector<std::string> types;
types.push_back("type1");
types.push_back("type2");
types.push_back("type3");
return types;
}
Run Code Online (Sandbox Code Playgroud)
这仅仅是一种风格选择还是我缺少的东西?任何帮助将不胜感激.对不起,如果这太基础了.
更新: 实际上发现覆盖相同方法的不同类可以这样或那样做,所以它更加含糊不清.我会让它们都一样,但如果有的话,我会更喜欢更好的方法.
编辑
请注意,上面的遗留代码不正确,因为它只使用数组的前两个元素初始化向量.但是,此错误已在评论中讨论过,因此应予以保留.
正确的初始化应该如下所示:
...
return std::vector<std::string> (types, types + 3);
...
Run Code Online (Sandbox Code Playgroud) 我有一个名字std::string,我想通过std::ostream接口填充数据,避免字符串副本.
执行此操作涉及副本的一种方法是执行此操作:
bool f(std::string& out)
{
std::ostringstream ostr;
fillWithData(ostr);
out = ostr.str(); // 2 copies here
return true;
}
Run Code Online (Sandbox Code Playgroud)
我需要传递结果out,不能返回 ostr.str().
我想避免副本,out = ostr.str();因为这个字符串可能非常大.
是否有某种方式,可能使用rdbuf()s,将std::ostream缓冲区直接绑定到out?
为了澄清,我很感兴趣的是自动扩展的行为std::string,并std::ostream让来电者不必知道调用之前的大小.
更新:我刚刚意识到无害线out = ostr.str();可能需要2份副本:
str()电话std::string赋值运算符.void changeString(const char* &s){
std::string str(s);
str.replace(0, 5, "Howdy");
s = str.c_str();
}
int main() {
const char *s = "Hello, world!";
changeString(s);
std::cout << s << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时,它会打印出"你好,世界!" 我认为退出str时会被摧毁changeString.我错过了std::string分配方式的东西吗?
我的问题与在C++中使用"s"后缀有关?
使用"s"后缀的代码示例:
auto hello = "Hello!"s; // a std::string
Run Code Online (Sandbox Code Playgroud)
同样可以写成:
auto hello = std::string{"Hello!"};
Run Code Online (Sandbox Code Playgroud)
我能够在网上找到"s"后缀应该用于最小化错误并澄清我们在代码中的意图.
因此,使用"s"后缀仅仅是为了代码的读者?或者还有其他优势吗?
为什么你可以在std :: basic_string中插入一个'\ 0'字符,而.length()方法不受影响,但如果你调用,char_traits<char>::length(str.c_str())你可以获得字符串的长度直到第一个'\ 0'字符?
例如
string str("abcdefgh");
cout << str.length(); // 8
str[4] = '\0';
cout << str.length(); // 8
cout << char_traits<char>::length(str.c_str()); // 4
Run Code Online (Sandbox Code Playgroud) 我有一个struct看起来像这样:
struct queue_item_t {
int id;
int size;
std::string content;
};
Run Code Online (Sandbox Code Playgroud)
我有一个std::vector< queue_item_t >从数据库查询中填充了许多这些.
处理每个项目时,将从磁盘读取文件,并将其内容放入content字符串成员中.该项目被处理(content被解析),我.clear()在字符串上执行,以免占用我的所有记忆.
但是,这似乎并没有释放内存.我有数十万个项目正在处理中,最终,内存使用量将超出可用范围,并且应用程序被Linux以"内存不足"为原因杀死.
如何释放这些字符串使用的内存?
问题来自于C++ Primer第5版的练习:
编写一个程序,将char*指针列表中的元素分配给C风格的字符串到一个字符串向量.
---------------- Oringinal Question ------------
首先,我尝试以下有点直接的方式:
vector<char *> vec = {"Hello", "World"};
vec[0][0] = 'h';
Run Code Online (Sandbox Code Playgroud)
但编译代码我收到警告:
temp.cpp:11:43: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
vector<char *> vec = {"Hello", "World"};
^
Run Code Online (Sandbox Code Playgroud)
运行./a.out我得到了一个
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)
我想是因为我试着写一个const char.所以我尝试另一种方式:
char s1[] = "Hello", s2[] = "World";
vector<char *> vec = {s1, s2};
vec[0][0] = 'h';
Run Code Online (Sandbox Code Playgroud)
这次没关系.但这似乎有点单调乏味.有没有其他优雅的方法来初始化字符串文字的向量?
这个程序(用选项编译-std=c++17)
#include <stdio.h>
#include <string>
void* operator new(std::size_t nrOfBytes) {
printf("allocate %zd bytes on heap\n", nrOfBytes);
void* p = malloc(nrOfBytes);
if (p) {
return p;
} else {
throw std::bad_alloc{};
}
}
int main() {
// new operator is called when compiled with Clang or MSVS or GCC
int* i = new int;
delete i;
// new operator is not called when compiled with GCC
// but is called with Clang and MSVS
std::string str(2000, 'x');
return 0; …Run Code Online (Sandbox Code Playgroud) 如何删除向量alphabets中与字符串中的任何字符匹配的元素plaintext?
这是我的尝试:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
//init
std::vector<std::string> alphabets{ "a", "b", "c", "d", "e", "f", "g", "h", "i", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
//input
std::string plaintext;
std::cout << "enter plain text: ";
std::cin >> plaintext;
for (std::string::iterator it = plaintext.begin(); it != plaintext.end(); it++)
{
std::vector<std::string>::iterator toErase;
toErase = std::find(alphabets.begin(), alphabets.end(), *it);
if (toErase != alphabets.end())
{ …Run Code Online (Sandbox Code Playgroud) 我们如何区分 C++ 中的字符数组和字符串?有什么 char 数组比 std::string 做得更好的吗?