【问题标题】:strcat alternative issue C++strcat 替代问题 C++
【发布时间】:2013-02-24 21:33:57
【问题描述】:

我正在处理一个最初用 C 进行采样但想用 C++ 进行的项目。

有一个部分使用了 strcat(),我被告知要使用替代方法。我找到了一个here,但是当我尝试这些时,编译器给了我以下错误:

错误:char*' andchar*' 到二进制 `operator+' 类型的无效操作数

是不是我做错了什么?

编辑:

这是代码中不起作用的部分

FILE *FileOpen(string *fname, string* mode){
FILE *fp;
string *str = "";

str += "tmp/"; //all files to be created in temporary sub directory
str += fname;
if((fp=fopen(str,mode))==NULL){
fprintf(stderr,"Cannot open file: %s\n", &fname);
exit(1);
}
FileReader(fname);
return(fp);
}

编辑 2: 对于那些想知道为什么我有 FileReader 的人:这是项目的第 2 部分。反汇编代码。

【问题讨论】:

  • 是的,因为char*std::string 不同。
  • 请贴出错误代码
  • “我做错了什么吗?”显然是的。如果你不这样做,你就不会出错。现在,如果你想问什么你做错了什么......以善良的名义,我们应该如何在没有看到你的代码的情况下知道?
  • 请把那个引用扔到很远的地方。我发现了这个小宝石:strcpy(str, strcat(str1, str2));,并声称它与str = str1+str2; 相同。 (不是,因为它会更改 str1 并且如果 str1 是常量/字符串文字或没有为连接分配足够的存储空间,则会导致未定义的行为)

标签: c++ operators strcat


【解决方案1】:

感谢您发布代码;现在问题很明显了。

你应该使用字符串对象,而不是指向它们的指针。

FILE *FileOpen(string fname, string mode)
{
    string str = "";

    str += "tmp/"; //all files to be created in temporary sub directory
    str += fname;
    FILE *fp = fopen(str.c_str(), mode.c_str());
    if (!fp) {
        fprintf(stderr, "Cannot open file: %s\n", fname.c_str());
        exit(1);
    }
    FileReader(fname);
    return fp;
}

下一步的好方法是转向接受std::string 参数的I/O 函数,这样您就不必到处说.c_str()

我也很困惑为什么你的文件打开函数中有FileReader(fname)。这两次违反了单一职责原则。打开一个文件不应该导致它被读取,读取文件的代码应该使用FILE*,而不关心文件名是什么(除了可能生成错误消息)。

【讨论】:

  • 我有用于项目第二部分(反汇编程序)的 FileReader。
  • @JulioGarcia:当然你需要FileReader,但不是在这个函数内部。它可能应该在调用此函数之后从您的主例程中调用。
  • 好的,知道了。现在我在 FileReader 上有一个问题。我应该把它放在这里还是放在另一个问题上? >.>;;
  • 谢谢@OlafDietsche,两者兼而有之。与 FileOpen 和它自己的小世界有关。
  • @JulioGarcia 那么这是你的电话,你选择哪一个。虽然一个新问题通常比一个已经有多个答案的旧问题更受关注。
【解决方案2】:

你没有显示任何代码,但我怀疑你有类似的东西

char *s1 = "Hello, ", *s2 = "world!";
char buf[50];
strcpy(buf, s1);
strcat(buf, s2);

现在你把它改成了

char *s1 = "Hello, ", *s2 = "world!";
char buf[50];
buf = s1 + s2;

这不起作用,正如您已经注意到的那样。您还必须将 char 指针和 char 数组更改为 std::string

std::string s1 = "Hello, ", s2 = "world!";
std::string buf = s1 + s2;

【讨论】:

    【解决方案3】:

    如果您的代码使用char * 作为字符串,那么strcat 可能是适合您的函数。当然,C++ 解决方案是使用std::string,在这种情况下您可以只使用+ - 因为std::string 有二进制operator+

    【讨论】:

    • 好吧,我把 char 改成 string 得到同样的结果。
    • 你怎么能从 std::string 获得error: invalid operands of types char*' andchar*' to binary operator+'`?或者当您说“相同的结果”时,您的意思是“我得到了一个错误”?我猜我猜你代码的技巧没用.. ;)
    • @MatsPetersson,我认为 OP 可能已经完成了 std::string s = "abc" + "def"; 或类似的事情。
    • @JulioGarcia:您不应该将char 更改为string,这将留下string*。您应该将char* 更改为string
    【解决方案4】:

    好吧,C++ 有一个字符串类std::string,它的 operator+ 执行连接。但是你必须先创建一个。

    所以表达式"abc" + "def" 无法编译,但std::string("abc")+"def" 可以正常工作。

    或者你可以写类似的东西

    std::string s("abc");
    s += "def";
    

    同样,

    std::string s = "abc";
    s += "def";
    

    如果您想连接大量文本,并且关心性能,请考虑使用std::ostringstream

    【讨论】:

    • 您为什么认为 ostringstream 仅用于连接字符串会更高效?
    • @yonil,所有符合 C++11 的实现都可以。
    • @yonil:你不认为std::stringstream 使用连续内存吗?指数缓冲区扩展是它更快的原因,与不连续性无关。
    • 我之前在那条评论中写了完全废话,对此感到抱歉。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    • 2010-11-28
    • 2013-08-23
    • 2017-07-18
    相关资源
    最近更新 更多