Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何连接多个C++;一行上的字符串?_C++_String_Compiler Errors_Concatenation - Fatal编程技术网

C++ 如何连接多个C++;一行上的字符串?

C++ 如何连接多个C++;一行上的字符串?,c++,string,compiler-errors,concatenation,C++,String,Compiler Errors,Concatenation,C#有一个语法特性,可以在一行中将许多数据类型连接在一起 string s = new String(); s += "Hello world, " + myInt + niceToSeeYouString; s += someChar1 + interestingDecimal + someChar2; < C++中的等价物是什么?就我所见,您必须在单独的行中完成所有操作,因为它不支持带+运算符的多个字符串/变量。这没问题,但看起来没那么整洁 string s; s += "Hello wo

C#有一个语法特性,可以在一行中将许多数据类型连接在一起

string s = new String();
s += "Hello world, " + myInt + niceToSeeYouString;
s += someChar1 + interestingDecimal + someChar2;
< C++中的等价物是什么?就我所见,您必须在单独的行中完成所有操作,因为它不支持带+运算符的多个字符串/变量。这没问题,但看起来没那么整洁

string s;
s += "Hello world, " + "nice to see you, " + "or not.";
上面的代码产生一个错误

s += "Hello world, " + "nice to see you, " + "or not.";

这些字符数组文字不是C++ STD::字符串-需要转换它们:

s += string("Hello world, ") + string("nice to see you, ") + string("or not.");
要转换int(或任何其他可流式处理类型),可以使用boost词法转换或提供自己的函数:

template <typename T>
string Str( const T & t ) {
   ostringstream os;
   os << t;
   return os.str();
}
boost::格式

或std::stringstream

std::stringstream msg;
msg << "Hello world, " << myInt  << niceToSeeYouString;
msg.str(); // returns std::string object
std::stringstream msg;
msg
#包括
#包括
std::stringstream-ss;

ss您必须为每个要关联到字符串的数据类型定义运算符+(),但是由于运算符您的代码可以写成1

…但我怀疑这就是你想要的。在您的情况下,您可能正在查找流:

std::stringstream ss;
ss << "Hello world, " << 42 << "nice to see you.";
std::string s = ss.str();
std::stringstream-ss;
ss这对我很有用:

#include <iostream>

using namespace std;

#define CONCAT2(a,b)     string(a)+string(b)
#define CONCAT3(a,b,c)   string(a)+string(b)+string(c)
#define CONCAT4(a,b,c,d) string(a)+string(b)+string(c)+string(d)

#define HOMEDIR "c:\\example"

int main()
{

    const char* filename = "myfile";

    string path = CONCAT4(HOMEDIR,"\\",filename,".txt");

    cout << path;
    return 0;
}

要提供一个多行的解决方案:可以实现一个函数
concat
,将基于“经典”stringstream的解决方案简化为一个单语句。 它基于可变模板和完美转发


用法:

std::string s = concat(someObject, " Hello, ", 42, " I concatenate", anyStreamableType);
void addToStream(std::ostringstream&)
{
}

template<typename T, typename... Args>
void addToStream(std::ostringstream& a_stream, T&& a_value, Args&&... a_args)
{
    a_stream << std::forward<T>(a_value);
    addToStream(a_stream, std::forward<Args>(a_args)...);
}

template<typename... Args>
std::string concat(Args&&... a_args)
{
    std::ostringstream s;
    addToStream(s, std::forward<Args>(a_args)...);
    return s.str();
}

实施:

std::string s = concat(someObject, " Hello, ", 42, " I concatenate", anyStreamableType);
void addToStream(std::ostringstream&)
{
}

template<typename T, typename... Args>
void addToStream(std::ostringstream& a_stream, T&& a_value, Args&&... a_args)
{
    a_stream << std::forward<T>(a_value);
    addToStream(a_stream, std::forward<Args>(a_args)...);
}

template<typename... Args>
std::string concat(Args&&... a_args)
{
    std::ostringstream s;
    addToStream(s, std::forward<Args>(a_args)...);
    return s.str();
}
void addToStream(std::ostringstream&)
{
}
模板
void addToStream(std::ostringstream&a_流、T&&a_值、Args&&a_Args)
{

使用C++14用户定义的文本和
std::to_string
的\u流使代码变得更容易

using namespace std::literals::string_literals;
std::string str;
str += "Hello World, "s + "nice to see you, "s + "or not"s;
str += "Hello World, "s + std::to_string(my_int) + other_string;
请注意,可以在编译时连接字符串文字。只需删除
+

str += "Hello World, " "nice to see you, " "or not";

为此,您可以使用此标题:


在引擎盖下,您将使用std::ostringstream。

在5年内,没有人提到过
。附加

#include <string>

std::string s;
s.append("Hello world, ");
s.append("nice to see you, ");
s.append("or not.");
#包括
std::字符串s;
s、 附加(“你好,世界,”);
s、 附加(“很高兴见到你,”);
s、 附加(“或不附加”);

如果你写出
+=
,它看起来几乎和C一样#


如果您愿意使用
c++11
,您可以利用并定义两个函数模板,为
std::string
对象和任何其他对象重载加号运算符。唯一的陷阱是不要重载
std::string
的加号运算符,否则编译器不知道要使用哪个运算符。您可以这样做通过使用.After中的模板,字符串的行为类似于Java或C#。有关详细信息,请参阅我的示例实现

主代码
#包括
#包括“c_sharp_strings.hpp”
使用名称空间std;
int main()
{
int i=0;
浮点数f=0.4;
双d=1.3e-2;
字符串s;
s+=“你好,世界”,“很高兴见到你”
+"47+","f+","d,;
cout::value,std::string>::type
运算符+(标准::字符串s,ti)
{
返回s+std::to_字符串(i);
}
模板内联
typename std::enable_if::value&&
!std::值是否相同&&
!std::is_same::value,std::string>::type
运算符+(ti,std::string s)
{
返回std::to_字符串(i)+s;
}
#endif//C_SHARP_STRING_H_包括在内

正如其他人所说,操作码的主要问题是操作符
+
没有连接
常量char*
;但是它可以与
std::string
一起工作

下面是另一个解决方案,它使用C++11 lambdas和
来表示每个
,并允许提供一个
分隔符来分隔字符串:

#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>

string join(const string& separator,
            const vector<string>& strings)
{
    if (strings.empty())
        return "";

    if (strings.size() == 1)
        return strings[0];

    stringstream ss;
    ss << strings[0];

    auto aggregate = [&ss, &separator](const string& s) { ss << separator << s; };
    for_each(begin(strings) + 1, end(strings), aggregate);

    return ss.str();
}
您还可以“扩展”字符串类,并选择您喜欢的运算符(也许您喜欢我的“拖缆”解决方案,以便在一行中真正做到这一点:

#include <iostream>
#include <sstream>
using namespace std;

class Streamer // class for one line string generation
{
public:

    Streamer& clear() // clear content
    {
        ss.str(""); // set to empty string
        ss.clear(); // clear error flags
        return *this;
    }

    template <typename T>
    friend Streamer& operator<<(Streamer& streamer,T str); // add to streamer

    string str() // get current string
    { return ss.str();}

private:
    stringstream ss;
};

template <typename T>
Streamer& operator<<(Streamer& streamer,T str)
{ streamer.ss<<str;return streamer;}

Streamer streamer; // make this a global variable


class MyTestClass // just a test class
{
public:
    MyTestClass() : data(0.12345){}
    friend ostream& operator<<(ostream& os,const MyTestClass& myClass);
private:
    double data;
};

ostream& operator<<(ostream& os,const MyTestClass& myClass) // print test class
{ return os<<myClass.data;}


int main()
{
    int i=0;
    string s1=(streamer.clear()<<"foo"<<"bar"<<"test").str();                      // test strings
    string s2=(streamer.clear()<<"i:"<<i++<<" "<<i++<<" "<<i++<<" "<<0.666).str(); // test numbers
    string s3=(streamer.clear()<<"test class:"<<MyTestClass()).str();              // test with test class
    cout<<"s1: '"<<s1<<"'"<<endl;
    cout<<"s2: '"<<s2<<"'"<<endl;
    cout<<"s3: '"<<s3<<"'"<<endl;
}
#包括
#包括
使用名称空间std;
类拖缆//用于单线串生成的类
{
公众:
拖缆&清除()//清除内容
{
ss.str(“”;//设置为空字符串
ss.clear();//清除错误标志
归还*这个;
}
模板

friend Streamer&operator实际问题是,在C++中,将字符串文本与
+
连接失败:

字符串s;

s+=“你好,世界,+”很高兴见到你,“+”或“+”;

上面的代码产生一个错误

s += "Hello world, " + "nice to see you, " + "or not.";
<>在C++中(也在C中),你可以通过把它们放在彼此的旁边来连接字符串文字:

string s0 = "Hello world, " "nice to see you, " "or not.";
string s1 = "Hello world, " /*same*/ "nice to see you, " /*result*/ "or not.";
string s2 = 
    "Hello world, " /*line breaks in source code as well as*/ 
    "nice to see you, " /*comments don't matter*/ 
    "or not.";
如果在宏中生成代码,这是有意义的:

#define TRACE(arg) cout << #arg ":" << (arg) << endl;
()

或者,如果您坚持对字符串文本使用
+
(如已建议的):

另一种解决方案为每个串联步骤组合一个字符串和一个
const char*

string s;
s += "Hello world, "
s += "nice to see you, "
s += "or not.";

像这样的东西对我有用

namespace detail {
    void concat_impl(std::ostream&) { /* do nothing */ }

    template<typename T, typename ...Args>
    void concat_impl(std::ostream& os, const T& t, Args&&... args)
    {
        os << t;
        concat_impl(os, std::forward<Args>(args)...);
    }
} /* namespace detail */

template<typename ...Args>
std::string concat(Args&&... args)
{
    std::ostringstream os;
    detail::concat_impl(os, std::forward<Args>(args)...);
    return os.str();
}
// ...
std::string s{"Hello World, "};
s = concat(s, myInt, niceToSeeYouString, myChar, myFoo);
名称空间详细信息{
void concat_impl(std::ostream&){/*什么都不做*/}
模板
void concat_impl(标准::ostream&os、常数T&T、参数和参数)
{

os基于上述解决方案,我为我的项目制作了一个类var_字符串,以简化生活。示例:

var_string x("abc %d %s", 123, "def");
std::string y = (std::string)x;
const char *z = x.c_str();
课程本身:

#include <stdlib.h>
#include <stdarg.h>

class var_string
{
public:
    var_string(const char *cmd, ...)
    {
        va_list args;
        va_start(args, cmd);
        vsnprintf(buffer, sizeof(buffer) - 1, cmd, args);
    }

    ~var_string() {}

    operator std::string()
    {
        return std::string(buffer);
    }

    operator char*()
    {
        return buffer;
    }

    const char *c_str()
    {
        return buffer;
    }

    int system()
    {
        return ::system(buffer);
    }
private:
    char buffer[4096];
};
#包括
#包括
类变量字符串
{
公众:
变量字符串(常量字符*cmd,…)
{
va_列表参数;
va_启动(args,cmd);
vsnprintf(buffer,sizeof(buffer)-1,cmd,args);
}
~var_string(){}
运算符std::string()
{
返回std::字符串(缓冲区);
}
运算符char*()
{
返回缓冲区;
}
常量字符*c_str()
{
返回缓冲区;
}
int系统()
{
返回::系统(缓冲区);
}
私人:
字符缓冲区[4096];
};

>在C11:

中,仍然在想是否有更好的C++?

< P>
void printMessage(std::string&& message) {
    std::cout << message << std::endl;
    return message;
}

将在C++20中打印:消息编号:10

auto s = std::format("{}{}{}", "Hello world, ", myInt, niceToSeeYouString);
在此之前,您可以对以下各项执行相同的操作:


免责声明:我是{fmt}的作者。

以下是一行解决方案:

#include <iostream>
#include <string>

int main() {
  std::string s = std::string("Hi") + " there" + " friends";
  std::cout << s << std::endl;

  std::string r = std::string("Magic number: ") + std::to_string(13) + "!";
  std::cout << r << std::endl;

  return 0;
}
#包括
#包括
int main(){
std::string s=std::string(“Hi”)+“there”+“friends”;
性病::可能有
string s0 = "Hello world, " "nice to see you, " "or not.";
string s1 = "Hello world, " /*same*/ "nice to see you, " /*result*/ "or not.";
string s2 = 
    "Hello world, " /*line breaks in source code as well as*/ 
    "nice to see you, " /*comments don't matter*/ 
    "or not.";
#define TRACE(arg) cout << #arg ":" << (arg) << endl;
int a = 5;
TRACE(a)
a += 7;
TRACE(a)
TRACE(a+7)
TRACE(17*11)
string s = string("Hello world, ")+"nice to see you, "+"or not.";
string s;
s += "Hello world, "
s += "nice to see you, "
s += "or not.";
auto s = string("one").append("two").append("three")
namespace detail {
    void concat_impl(std::ostream&) { /* do nothing */ }

    template<typename T, typename ...Args>
    void concat_impl(std::ostream& os, const T& t, Args&&... args)
    {
        os << t;
        concat_impl(os, std::forward<Args>(args)...);
    }
} /* namespace detail */

template<typename ...Args>
std::string concat(Args&&... args)
{
    std::ostringstream os;
    detail::concat_impl(os, std::forward<Args>(args)...);
    return os.str();
}
// ...
std::string s{"Hello World, "};
s = concat(s, myInt, niceToSeeYouString, myChar, myFoo);
var_string x("abc %d %s", 123, "def");
std::string y = (std::string)x;
const char *z = x.c_str();
#include <stdlib.h>
#include <stdarg.h>

class var_string
{
public:
    var_string(const char *cmd, ...)
    {
        va_list args;
        va_start(args, cmd);
        vsnprintf(buffer, sizeof(buffer) - 1, cmd, args);
    }

    ~var_string() {}

    operator std::string()
    {
        return std::string(buffer);
    }

    operator char*()
    {
        return buffer;
    }

    const char *c_str()
    {
        return buffer;
    }

    int system()
    {
        return ::system(buffer);
    }
private:
    char buffer[4096];
};
void printMessage(std::string&& message) {
    std::cout << message << std::endl;
    return message;
}
printMessage("message number : " + std::to_string(id));
auto s = std::format("{}{}{}", "Hello world, ", myInt, niceToSeeYouString);
auto s = fmt::format("{}{}{}", "Hello world, ", myInt, niceToSeeYouString);
#include <iostream>
#include <string>

int main() {
  std::string s = std::string("Hi") + " there" + " friends";
  std::cout << s << std::endl;

  std::string r = std::string("Magic number: ") + std::to_string(13) + "!";
  std::cout << r << std::endl;

  return 0;
}
#include <iostream.h> // for string

string myName = "";
int _age = 30;
myName = myName + "Vincent" + "Thorpe" + 30 + " " + 2019;
#include <sstream>
#define make_string(args) []{std::stringstream ss; ss << args; return ss;}() 
auto str = make_string("hello" << " there" << 10 << '$');