【问题标题】:C++ equivalent of .ToString().ToString() 的 C++ 等价物
【发布时间】:2011-09-27 05:13:39
【问题描述】:

必须有一个简单的方法来做到这一点......

// C# code
    for (int i = 0; i < 20; i++)
        doSomething(i.ToString() + "_file.bmp");

我正在尝试在 C++ 中执行此操作,但事实证明,最简单的事情在该语言中是最难完成的。主要是因为有一个问题:我被限制在一个库中,它只接受char*'s 作为函数的参数,这最终会出现在这个函数中,所以我几乎一直在玩char 数组。这是我目前所拥有的:

char* path[12];
for(int i = 0; i < 20; i++)
{
    sprintf(path[0],"%i_Card.bmp",i);
    cards[i] = new Card(i,path[0]);
}

问题是,这种方法最终会得到一个又大又长的无用字符串。

我必须透露这是为了学校作业,但回答这个问题不会决定我的成绩,它只会让应用程序的某个方面更容易一些。

【问题讨论】:

  • 你不一定会被char* 卡住——std::string 有一个方法c_str 可以返回一个具有相同内容的char*
  • 呃,不。 c_str 返回 const char*。很不一样;如果图书馆试图写信给char*,你就会遇到问题。

标签: c++ arrays string for-loop


【解决方案1】:

ToString 的 C++03 等价物是

std::stringstream stream;
stream << i;
std::string i_as_string = stream.str();

请注意,您也可以通过 ( std::stringstream() &lt;&lt; i ).str() 来完成此操作而无需中间变量。

在 C++11 中,std::lexical_cast&lt; std::string &gt;( i )std::to_string( i ) 都可以为您完成上述操作(也可以从 Boost 获得)和 std::to_string( i )

【讨论】:

    【解决方案2】:

    试试这个

    #include <stdio.h>
    #include <stdlib.h>
    
    itoa(i)
    

    atoi


    或者你可以走this路线:

    #include <sstream>
    
    int i = 5;
    std::string s;
    std::stringstream out;
    out << i;
    s = out.str();
    

    【讨论】:

    • 链接标题应该是itoa 而不是atoi
    • 来自链接的itoa 页面:“不是 C++ 的一部分”。
    • @MSalters:这让你感到困扰吗?我猜你可以使用stream,它需要3行代码而不是1行,但如果你需要 c++程序中的所有内容都是@ 987654330@ 而不是c,那么你可以使用我给出的第二种技术。顺便说一句,你在c++ 中为int 做什么,intc 的一部分
    • 它也不是 C 的一部分。没有引用那部分,因为它很明显(C 库是 C++ 的一部分)并且不相关(问题标记为 C++,而不是 C)。
    • 如果流方法对您来说太长,请将其包装起来(参见lexical_cast)。
    【解决方案3】:

    我发现您的代码中有几个错误。

    1) 您将“路径”声明为包含 12 个字符指针的数组,但没有为任何数组项分配内存。 sprintf 语句保证复制到垃圾内存中。我很惊讶这不会立即使您的程序崩溃。

    2) 即使为路径数组分配了内存,您的 sprintf 语句也会始终复制到 path[0] - 覆盖已经存在的内容。

    我怀疑您混淆了 C/C++ 中的 char 数组、字符串和字符串数组。也许下面的代码会有所帮助。我假设您的“Card”类不会将作为第二个参数传递的字符串的副本保存到成员变量(至少不复制它)。否则,它将指向堆栈内存 - 如果您的 Card 实例超过了创建它的函数,这可能是错误的。

    const size_t MAX_INTEGER_LENGTH = sizeof(int) * 4; // 4x the sizeof int will suffice no matter what the sizeof(int) is
    
    char szPostfix[] = "_Card.bmp"; 
    
    for(int i = 0; i < 20; i++)
    {
        char path[MAX_INTEGER_LENGTH + sizeof(szPostfix) + 1]; //+1 for null terminator
        sprintf(path,"%d%s",i, szPostfix);
        cards[i] = new Card(i,path);
    }
    

    【讨论】:

    • 一个问题,不过。我无法将 const char* 传递给 Card 的构造函数中调用的函数。它只接受 char* 的。
    • 啊,但是“path”不是“const char*”。我认为您不明白数组和指针在 C/C++ 中几乎是一回事。出于所有意图和目的,“路径”被声明为一个字符数组。但是当数组被传递给函数时,它们“优雅地退化为指针”。在这种情况下,“path”被传递给 Card,就好像它是一个“char *”一样。上面的代码有效。相信我。我唯一担心的是 Card 构造函数是否在返回之前修改了 path 的内容,或者它是否保留了该指针地址。
    • 这很完美,可以满足我的所有需求!非常感谢!
    • 太棒了。我只是希望你已经了解了 C 中数组、指针和字符串之间的关系。
    【解决方案4】:

    您可以使用std::string 并将其转换为使用std::string::c_str() 的c 字符串。但是,它返回一个 const char* 的 c 字符串。 const_cast 可用于取消与其关联的 const 的资格。

    #include <iostream>
    #include <string>
    using namespace std;
    
    void foo(char* str){
        cout << str << endl;
    }
    
    int main(){
    
        string str = "Hello World";
        foo(const_cast<char*>(str.c_str()));
    
        return 0;
    }
    

    输出:Hello World

    Demo

    【讨论】:

      【解决方案5】:

      在 C++ 中没有将对象转换为字符串的通用方法。您必须自己定义转换函数。对于基本类型,您可以使用 stringstream 将它们转换为字符串。

      #include <sstream>
      #include <iostream>
      
      using namespace std;
      
      int main(int argc, char* argv[])
      {
        stringstream ss;
        ss << 1;
        cout << ss.str();
      }
      

      还有更多关于stringstream here的信息

      【讨论】:

        【解决方案6】:

        从代码看来,它是一个文件名,Card 类应该将路径作为const char*。所以我认为以下是c++的做法。

        for(int i = 0; i < 20; i++)
        {
            std::stringstream out;
            out << i << "_Card.bmp";
            cards[i] = new Card(i,out.str().c_str());
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-11-27
          • 2010-10-05
          • 1970-01-01
          • 1970-01-01
          • 2022-12-08
          • 2011-04-02
          • 2021-10-15
          • 2013-10-20
          相关资源
          最近更新 更多