C++ string 初始赋值用char[]会乱码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ string 初始赋值用char[]会乱码相关的知识,希望对你有一定的参考价值。

一个string的参数,用char[]给他初始化。。为什么char里头的都是对的。。可是一用 string(char, n);这个来初始化。。string参数里的东西全部都乱码了呢?
情况是要读一个csv文件,用fscanf只能读起来存到char*里头去。。然后要转成string的东西怎么转呢?

  方法一:使用stringstream进行转换。
  示例:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(int argc, char *argv[])

stringstream sstr;
sstr.clear();
char * ch = new char[1024];
string s="abcd";
sstr<<s;//将s的值放到stringstream
sstr>>ch;//将stringstream中的值导出到ch
cout<<ch<<endl;
return 0;

/*
输出:abcd
*/

  方法二:运用basic_string::c_str转换或者使用basic_string::data()转换
  1)函数原型:const value_type *c_str( ) const;和const value_type *data( ) const;
  2)函数描述:basic_string::c_str将一个字符串的内容转化为一个c风格字符串的指针,basic_string::data返回原始数据序列。
  3)区别:data只是返回原始数据序列,没有保证会用traits::eos(),或者说\'\\0\'来作字符串结束。 当然,可能多数实现都这样做了。
  示例:

#include <string>
#include <iostream>
using namespace std;
int main( )

string str1 ( "Hello world" );
const char *ptr1 = 0;
ptr1= str1.data ( );
cout << "The modified string object ptr1 is: " << ptr1
<< endl;
// Converting a string to a C-style string
const char *c_str1 = str1.c_str ( );
cout << "The C-style string c_str1 is: " << c_str1
<< endl;

/*
输出:
The modified string object ptr1 is: Hello world
The C-style string c_str1 is: Hello world
*/
参考技术A char数组一定要以‘\0’结尾
例如:
要转换的字符串为”Huang“
定义 char c[6] ='H','u','a','n','g','\0'
再用string s(&c); 即可

若用char c[5] ='H','u','a','n','g''
再用string s(&c); 则会出现你那种情况本回答被提问者采纳
参考技术B string(char*, n) 初始化应该是没有问题的。string(char, n)这个就是有问题的。
另外,你的n计算是否正确。
实在不行就贴代码上来看看。
参考技术C 先把char[],字符数组初始化一下,再进行相关的操作。

在 C++ 中通过赋值初始化自己的 String 类

【中文标题】在 C++ 中通过赋值初始化自己的 String 类【英文标题】:initialize own String class by assignment in c++ 【发布时间】:2015-09-02 08:53:53 【问题描述】:

我正在用 c++ 编写自己的字符串类 StringEx(别担心,只是为了练习),但我无法通过为其分配字符串来创建我的类的实例:

StringEx string1 = StringEx("test"); // works fine
StringEx string2 = "test"; // doesn't work

string string3 = "test";
string1 = string3; // also works fine

我重载了赋值运算符,以便它可以处理std::string,但我必须先创建一个StringEx 的对象。

如何通过分配字符串来创建StringEx 的新对象?是否有可能让 c++ 处理每个 "string" 作为我的 StringEx 类的对象?

这是我的StringEx.h 现在可以使用

#ifndef STRINGEX_H
#define STRINGEX_H


#include <iostream>
#include <string>
#include <vector>
using namespace std; //simplyfying for now

class StringEx

private:
    vector<char> text;
public:
    StringEx();
    StringEx(string);
    StringEx(const char*);  // had to add this
    StringEx(vector<char>);

    int size() const;
    int length() const;
    char at(int) const;

    void append(const string&);
    void append(const StringEx&);
    void append(const char*);  // had to add this

    StringEx operator+(const string&);
    StringEx operator+(const StringEx&);
    StringEx operator+(const char*);  // had to add this too

    StringEx operator=(const string&);
    StringEx operator=(const StringEx&);
    StringEx operator=(const char*);  // had to add this too

    StringEx operator+=(const string&);
    StringEx operator+=(const StringEx&);
    StringEx operator+=(const char*);  // had to add this too

    friend ostream& operator<<(ostream&, const StringEx&);
;

#endif // STRINGEX_H

【问题讨论】:

这称为初始化(更准确地说,复制初始化),而不是赋值。赋值是在对象之前已经构造的时候(就像在你的上一个例子中一样)。 奇怪的是:这段代码在 VS2015 上编译得很好 你已经得到了一些答案,但你真的应该展示你的类的构造函数、复制构造函数和复制赋值的声明。 @SimonKraemer MSVC 从来都不是标准合规的典范。 @LPrulzcrossover 您的编辑显示了导致错误的StringEx.h,还是现在有效的StringEx.h?请编辑您的问题并解释您所展示的内容。 【参考方案1】:

一些精度:

StringEx string1 = StringEx("test"); // works fine

这使用复制构造函数,即StringEx(const StringEx&amp; other);

StringEx string2 = "test"; // doesn't work

这会尝试使用具有以下签名的构造函数:StringEx(const char* str);

最后,这两行:

string string3 = "test";
string1 = string3; // also works fine

从标准库定义的const char* 创建一个std::string,然后使用您似乎已正确定义的std::string 重载的复制赋值运算符,即StringEx&amp; operator=(const std::string&amp; other)

这里的重点是这样的说法:

Type myVar = something;

不是赋值,它是使用构造函数的变量的声明和初始化,而不是复制赋值运算符。

在您的情况下,您只是缺少一个将const char* 作为参数的构造函数

【讨论】:

原代码可以用MSVC14/VS2015编译,运行正常。即使 IDE 显示错误。 谢谢,现在可以使用了!是否有可能让 c++ 处理每个const char* 作为StringEx?为了得到即cout &lt;&lt; "hello" + "world";工作。 @LPrulzcrossover 你不能隐含地(好吧,也许你可以用一种我不知道的非常丑陋的方式)。你为什么要那样做?该行可以使用适当的 operator+ 重载来处理两个 const char*,例如返回 std::string 是否有可能为两个const char* 重载operator+?考虑到this,答案似乎是否定的,或者你会怎么做? 之前应该检查过,实际上不可能。 §13.5.6 中的 C++ 标准规定,在重载二元运算符时,至少一个参数类型必须是类、对类的引用、枚举或对枚举的引用。我的错。【参考方案2】:

我假设你有一个表单的非显式构造函数

StringEx (const std::string&);

或类似的。

字符串文字不是std::string 类型。 "test" 的类型为 const char[5]std::string 有一个接受const char* 的非显式构造函数,所以你的两个调用看起来像这样(不考虑复制省略):

//implicitly convert "test" to temporary std::string
//construct temporary StringEx with temporary std::string
//copy-construct StringEx with temporary
StringEx string1 = StringEx("test"); 

//no StringEx constructor taking const char*
//two conversions necessary to make "test" into a StringEx
//invalid
StringEx string2 = "test";

一个简单的解决方法是添加一个构造函数,将const char* 设置为StringEx

StringEx (const char*);

或者你也可以使用直接初始化:

//only one conversion needed
StringEx string2 ("test");

【讨论】:

【参考方案3】:

TLDR:如果需要 2 次“强制转换”,编译器不会自动解析。在这种情况下,const char*std::stringStringEx


StringEx string1 = StringEx("test"); // works fine > 这会显式调用构造函数,因此只需进行一次转换:const char*std::string

StringEx string2 = "test"; // doesn't work > 另一方面,这并不清楚。你想将const char* 转换为std::string 并使用StringEx(const std::string&amp;)constructor 还是使用其他中间类?

你需要的是另一个接受const char*作为参数的构造函数。

顺便说一句:

StringEx string4 = std::string("test"); //Also works

【讨论】:

以上是关于C++ string 初始赋值用char[]会乱码的主要内容,如果未能解决你的问题,请参考以下文章

关于C++中string类型变量的赋值

c++中定义一个buff为unsigned char 型,如何初始化全为0

c++string详解

c++里边string类用数组的形式输入为啥无法用cout输出?

在 C++ 中通过赋值初始化自己的 String 类

c++ 把string类型的h1,赋值给vector<string>类型的h2