【问题标题】:How to convert string to char * in C++?如何在 C++ 中将字符串转换为 char *?
【发布时间】:2012-03-07 18:33:29
【问题描述】:

如何将string 转换为char * 我正在使用以下方法,但它不起作用。

在运行时它给了我以下错误:

运行时检查失败 #3 - 变量 'url' 没有被使用 正在初始化。

尽管我已经按照下面的代码对其进行了初始化。可以举个例子吗?

    char* url;
    sup = "news"
    sup="http://www."+sup+"yahoo.com";
    strcpy(url, sup.c_str());

我在控制台中使用 Microsoft Visual Studio 2010,C++

【问题讨论】:

  • 如果您只想使用字符指针,您可以简单地使用 sup.c_str() 而不是再次为变量 'url' 分配相等数量的字节。
  • @Unni 虽然它会是一个 const char*(不仅仅是一个 char*)。但我同意这可能是实际需要的。
  • 我会在任何地方使用std::string,直到您需要将其传递给遗留系统。然后使用std::string::c_str()。你有什么理由不能使用std::string

标签: c++ visual-c++


【解决方案1】:

strcpy不给你分配内存,你必须自己做,记得给空终止符留空间:

char* url = new char[sup.length()+1];

char url[sup.length()+1];
//...
strcpy(url, sup.c_str());

在第一种情况下,不要忘记delete[] 数组。仅当您的编译器支持 C99 可变长度数组作为扩展时,第二种情况才有效。

【讨论】:

  • 它可能运作良好,但我认为这不是最佳答案。你总是急于接受第一个有效的答案,而不是等着看别人怎么说?我不喜欢这个答案的原因是,在 C++ 中,您应该避免使用 new to 和 raw 数组,但应该更喜欢使用 vector。 boost::shared_array 如果你真的觉得你必须使用 new 将是另一种选择。我不特别喜欢第二个身体,因为它选择了任意尺寸,然后希望它适合而不需要任何检查。其实我也不知道为什么第一个区块会选择 32。
  • @CashCow 呃,没有。给出的答案是 C 中的一个很好的标准做法。您使用 boost 或 vector 的答案不直观且(IMO)混乱。
  • @adelphus:问题是关于 C++,而不是 C;即使在 C 中,使用strcpy 而不检查潜在的缓冲区溢出也是一个非常糟糕的主意。除非你在做一些奇怪的事情,否则当你想要一个字符串时使用std::string
  • 我猜我认为缓冲区足够了。您可以找到长度并根据需要分配尽可能多的内存。但在这种情况下,他似乎知道字符串的最大大小。
  • @LuchianGrigore:由于supstd::string,因此您无需猜测长度。 vector<char>(sup.length()+1) 会给你你需要的数组,假设 OP 出于某种原因确实需要一个数组。
【解决方案2】:

在我看来,有两种方法可以做到这一点。

  1. 使用 & 运算符(和号)

    string str = "hello";
    char *p;
    p = &str[0];
    
  2. 使用 c_str() 函数

    string s = "hello";
    const char *p; 
    p = s.c_str();
    

我都测试过,它们都在工作。如果我错了,请纠正我。

【讨论】:

  • 当你测试它时它可能会工作,但第一个有点小技巧,不能保证工作。例如。如果字符串的内部表示是一个块列表而不是单个内存块,那么当你尝试这个时你不会得到整个字符串。因此 c_str() 的存在是为了强制字符串创建单个内存块并以零结尾。
  • 这是最好的解决方案。
【解决方案3】:

strcpy 不安全,因为可能会发生缓冲区溢出。使用strncpy 提供要复制的确切字节数。您需要为目标缓冲区分配内存并添加尾随\0

std::string strInsert("news");
std::string sup("http://www.");
sup += strInsert + "yahoo.com";

char* url = new char[sup.length() + 1];
strncpy(url, sup.c_str(), sup.length());
url[sup.length()] = '\0';
// ... use url
delete[] url;

【讨论】:

    【解决方案4】:
    char* url = new char[100];
    

    你必须先为你的 char 数组分配内存。

    【讨论】:

      【解决方案5】:

      如果您确实需要从 std::string 的内容复制的可写 char 缓冲区,您可以使用 std::vector<char>

      std::vector<char> urlAsVec( sup.begin(), sup.end() );
      urlAsVec.push_back( '\0' );
      char * url = &urlAsVec[0]; // pointer you can safely write to
      

      你也可以这样初始化向量:

      std::vector<char> urlAsVec( sup.c_str(), sup.c_str() + sup.size() + 1 );
      

      它也会为你编写你的空终止符。

      另一种选择:

      std::vector<char> urlAsVec( sup.size() + 1 );
      sup.copy( &urlAsVec[0], sup.size() );
      

      请注意,您的向量将自动将其所有元素初始化为 0,因此即使 sup.copy() 没有写入它,空终止符也会存在。无论如何,您都可以使用sup.copy( ptr, len) 而不是 strcpy,这会稍微安全一些,因为您可以指定缓冲区大小(尽管 strncpy 也允许这样做),尽管您仍然必须手动编写空终止符(或已经分配) .

      例如,如果你使用这个:

      char url[ BUFLEN ] = {0};
      sup.copy( url, BUFLEN-1 );
      

      对于某些固定值 BUFLEN,您将获得写入缓冲区的源字符串的副本或部分副本。请注意,我的初始化程序确保所有未写入的字节都是 0。

      【讨论】:

        【解决方案6】:

        sup 复制到url 并不意味着你已经初始化了url
        初始化url 意味着为其分配内存。像这样:

        url = new char[size];
        

        【讨论】:

          【解决方案7】:
          std::string sup = "news";
          sup="http://www."+sup+"yahoo.com";
          char* url = new char[sup.length()+1];
          url = const_cast<char*>(sup.c_str());
          url[sup.length()] = '\0';
          
          std::cout<<url;            //http://www.newsyahoo.com
          

          注意网址末尾的'\0'

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-03-27
            • 2013-05-13
            • 2012-01-16
            相关资源
            最近更新 更多