如何干净使用:const char *和std :: string? [英] How to cleanly use: const char* and std::string?

查看:270
本文介绍了如何干净使用:const char *和std :: string?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


tl:dr



如何连接 const char * std :: string ,整齐和
优雅,没有多个函数调用。理想情况下,在一个函数
调用并且输出为 const char * 。这是不可能的,什么
是最佳解决方案?




初始问题


$ b b

到目前为止,C ++所遇到的最大障碍是如何处理字符串。在我看来,在所有广泛使用的语言,它处理字符串最差。我看到类似的其他问题,或者有一个回答说使用 std :: string 或者只是指出,其中一个选项是最好的你的情况。



然而,当尝试动态使用字符串,如同在其他语言中使用字符串时,这是无用的建议。我不能保证总是能够使用 std :: string 和当我必须使用 const char * 我打了明显的墙它是不变的,你不能连接它。



我在C ++中看到的任何字符串操作问题的每个解决方案都需要重复的多行代码,只能对该字符串格式有效。
我想能够使用 + 符号连接任何字符集,或者使用一个简单的 format()函数只是我可以在C#或Python。

标准输出

p>

我正在写一个DLL,到目前为止我已通过 cout ><< 运算符。到目前为止,使用以下形式的简单字符数组,一切都很好:

  cout< 你好,世界! 

运行时字符串



现在,我想要在运行时构建一个字符串并存储它的类,这个类将保存一个字符串报告一些错误,以便他们可以被其他类拾取,并可能发送到 cout 以后,该字符串将由函数 SetReport(const char * report)设置。所以我真的不想使用多行,因此我继续写下如下:

  SetReport 失败+ __FUNCTION__ +:foobar是+ foobar +\\\
); // __FUNCTION__获取当前函数的名称,foobar是一些变量




  • 表达式必须具有整型或无作用范围的枚举类型和...

  • '+':不能添加两个指针



丑陋字符串



右键。所以我试图添加两个或更多 const char * 在一起,这只是不是一个选项。所以我发现这里的主要建议是使用 std :: string ,这种奇怪的输入Hello world!不只是给你一个,但让我们一起去:

  SetReport(std: :string(Failure in)+ std :: string(__ FUNCTION__)+ std :: string(:foobar was)+ std :: to_string(foobar)+ std :: string(\\\
));

辉煌!有用!但看看这是多么丑陋!这是我见过的最丑陋的代码。我们可以简化为:

  SetReport(std :: string(Failure in)+ __FUNCTION__ +:foobar is + std :: to_string(foobar)+\\\
);

仍然可能是最糟糕的方式,我遇到了一个简单的一行字符串连接,但一切


$ b

如果你正在处理一个DLL,我倾向于做很多,因为我喜欢单元测试,所以我需要我的C ++代码由单元测试库导入,你会发现,当你尝试设置报告字符串到类的成员变量作为 std :: string ,编译器会引发一个警告:

 警告C4251:类'std :: basic_string< _Elem,_Traits,_Alloc>'需要具有dll-接口供类'
/ pre>

我发现除了忽略警告(坏习惯!)之外,这个问题的唯一真正的解决方案是使用 const char * 为成员变量而不是 std :: string ,但这不是一个真正的解决方案,因为现在你必须转换你的丑陋连接(但动态)字符串回到你需要的const char数组。但你不能只是标记 .c_str()在结束(即使你为什么要,因为这种连接变得更加可笑的第二个?)你必须请确保 std :: string 不会清除新构造的字符串并留下垃圾。所以你必须在接收字符串的函数里面这样做:

  const std :: string constString = 
m_constChar = constString.c_str();

这是疯了。因为现在我跨越几种不同类型的字符串,使我的代码丑陋,添加更多的行,而不是需要,所有只是把一些字符在一起。为什么这么难?



解决方案?



我觉得我应该能够创建一个连接 const char * s的函数,但也可以处理其他对象类型,例如 std :: string int double ,我强烈认为这应该能够在一行,但我无法找到任何实现它的实现。我应该使用 char * 而不是常量变量,即使我已经阅读,你不应该更改 char * 这将如何帮助?



有没有经验的C ++程序员已经解决了这个问题,现在舒服的C ++字符串,你的解决方案是什么?有没有解决方案?是不可能的。

解决方案

最简单的解决方案之一是使用一个 C ++空字符串。这里我声明一个名为 _ 的空字符串变量,并在字符串连接之前使用它。确保你总是把它放在前面。

  #include< cstdio> 
#include< string>

using namespace std;
string _ =;

int main(){
char s [] =chararray;
string result =
_ +function name = [+ __FUNCTION__ +]
and s is [+ s +] \\\

printf(%s,result.c_str());
return 0;
}

输出:

  function name = [main] and s is [chararray] 

关于 __ FUNCTION __ ,我发现在Visual C ++它是一个宏,而在GCC它是一个变量,因此 SetReport(Failure in__FUNCTION__ ; foobar是+ foobar +\\\
);
将只适用于Visual C ++。请参阅: https://msdn.microsoft.com/en-us/library/b0084kay .aspx https://gcc.gnu.org/onlinedocs/ gcc / Function-Names.html



上面的使用空字符串变量的解决方案应该同时适用于Visual C ++和GCC。


tl:dr

How can I concatenate const char* with std::string, neatly and elegantly, without multiple function calls. Ideally in one function call and have the output be a const char*. Is this impossible, what is an optimum solution?

Initial Problem

The biggest barrier I have experienced with C++ so far is how it handles strings. In my opinion, of all the widely used languages, it handles strings the most poorly. I've seen other questions similar to this that either have an answer saying "use std::string" or simply point out that one of the options is going to be best for your situation.

However this is useless advice when trying to use strings dynamically like how they are used in other languages. I cannot guaranty to always be able to use std::string and for the times when I have to use const char* I hit the obvious wall of "it's constant, you can't concatenate it".

Every solution to any string manipulation problem I've seen in C++ requires repetitive multiple lines of code that only work well for that format of string. I want to be able to concatenate any set of characters with the + symbol or make use of a simple format() function just how I can in C# or Python. Why is there no easy option?

Current Situation

Standard Output

I'm writing a DLL and so far I've been output text to cout via the << operator. Everything has been going fine so far using simple char arrays in the form:

cout << "Hello world!"

Runtime Strings

Now it comes to the point where I want to construct a string at runtime and store it with a class, this class will hold a string that reports on some errors so that they can be picked up by other classes and maybe sent to cout later, the string will be set by the function SetReport(const char* report). So I really don't want to use more than one line for this so I go ahead and write something like:

SetReport("Failure in " + __FUNCTION__ + ": foobar was " + foobar + "\n"); // __FUNCTION__ gets the name of the current function, foobar is some variable

Immediately of course I get:

  • expression must have integral or unscoped enum type and...
  • '+': cannot add two pointers

Ugly Strings

Right. So I'm trying to add two or more const char*s together and this just isn't an option. So I find that the main suggestion here is to use std::string, sort of weird that typing "Hello world!" doesn't just give you one of those in the first place but let's give it a go:

SetReport(std::string("Failure in ") + std::string(__FUNCTION__) + std::string(": foobar was ") + std::to_string(foobar) + std::string("\n"));

Brilliant! It works! But look how ugly that is!! That's some of the ugliest code I've every seen. We can simplify to this:

SetReport(std::string("Failure in ") + __FUNCTION__ + ": foobar was " + std::to_string(foobar) + "\n");

Still possibly the worst way I've every encounter of getting to a simple one line string concatenation but everything should be fine now right?

Convert Back To Constant

Well no, if you're working on a DLL, something that I tend to do a lot because I like to unit test so I need my C++ code to be imported by the unit test library, you will find that when you try to set that report string to a member variable of a class as a std::string the compiler throws a warning saying:

warning C4251: class 'std::basic_string<_Elem,_Traits,_Alloc>' needs to have dll-interface to be used by clients of class'

The only real solution to this problem that I've found other than "ignore the warning"(bad practice!) is to use const char* for the member variable rather than std::string but this is not really a solution, because now you have to convert your ugly concatenated (but dynamic) string back to the const char array you need. But you can't just tag .c_str() on the end (even though why would you want to because this concatenation is becoming more ridiculous by the second?) you have to make sure that std::string doesn't clean up your newly constructed string and leave you with garbage. So you have to do this inside the function that receives the string:

const std::string constString = (input);
m_constChar = constString.c_str();

Which is insane. Because now I traipsed across several different types of string, made my code ugly, added more lines than should need and all just to stick some characters together. Why is this so hard?

Solution?

So what's the solution? I feel that I should be able to make a function that concatenates const char*s together but also handle other object types such as std::string, int or double, I feel strongly that this should be capable in one line, and yet I'm unable to find any examples of it being achieved. Should I be working with char* rather than the constant variant, even though I've read that you should never change the value of char* so how would this help?

Are there any experienced C++ programmers who have resolved this issue and are now comfortable with C++ strings, what is your solution? Is there no solution? Is it impossible?

解决方案

One of the simplest solution is to use an C++ empty string. Here I declare empty string variable named _ and used it in front of string concatenation. Make sure you always put it in the front.

#include <cstdio>
#include <string>

using namespace std;
string _ = "";

int main() {
        char s[] = "chararray";
        string result =
                _ + "function name = [" + __FUNCTION__ + "] "
                "and s is [" + s + "]\n";
        printf( "%s", result.c_str() );
        return 0;
}

Output:

function name = [main] and s is [chararray]

Regarding __FUNCTION__, I found that in Visual C++ it is a macro while in GCC it is a variable, so SetReport("Failure in " __FUNCTION__ "; foobar was " + foobar + "\n"); will only work on Visual C++. See: https://msdn.microsoft.com/en-us/library/b0084kay.aspx and https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html

The solution using empty string variable above should work on both Visual C++ and GCC.

这篇关于如何干净使用:const char *和std :: string?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆