printf和自定义类

printf and custom class

本文关键字:自定义 printf      更新时间:2023-10-16

我有自己的类,它表示一个自定义字符串类。我使用的是VS2012RC。我已经重载了类CustomString的一些运算符。

这里有一些代码:

CustomString::CustomString(string setstr)
{           
    str = setstr;
}
CustomString::operator const char *()
{   
    return (this->str.c_str());
}
CustomString &CustomString::operator = (char *setstr)
{
    str = setstr;
    return *this;
}

我可以定义我的对象并像这样使用它:

CustomString str = "Test string";

我可以将结果打印为:

printf(str);
printf((string)(str).c_str());
printf((string)(str).data());
printf("%sn",(string)(str).c_str());
printf("%sn",(string)(str).data());

而且没有任何错误。

但如果我这样使用它:

printf("%sn", str);

msvcr110d.dll中存在异常(内存访问错误)

为什么printf(str)可以,而print f("%s\n",str)[/strong>不可以?

如何修改代码以使用printf("%s\n",str)

经过数小时的谷歌搜索,我发现explit-cast(string)、static_cast(str)和_str()方法添加了一个以null结尾的字符:"\0";

我已将代码修改为:

printf("%sn",str + '');

它成功了!

有没有任何方法可以修改我的自定义构造函数,添加一个以null结尾的字符串,并用null结尾的字符传递一个正确的值来处理以下代码:

printf("%sn",str);

不要使用printf,它比C++更像C。相反,使用iostreams,它为您提供了一种设置自己的自定义类格式并将发送到文件或stdout的工具。

以下是一个可能对您有效的快速(未经测试)示例:

std::ostream& operator<< (std::ostream &os, const CustomString& str)
{ 
    os << str.data();
    return os; 
} 

你可以通过做一些类似的事情将自定义字符串打印到stdout

CustomString str;
// put some text in the custom string, then:
std::cout << str << std::endl;

您不能(至少不能以可移植的方式)。printf查看作为参数传递的对象,并将其视为%s,这是一个char数组。您遇到了未定义的行为。此外,传递给printf的参数有点像是无类型的。

为什么printf(str)可以?

因为第一个参数是类型,并且是const char*。隐式强制转换是通过运算符进行的。其余参数的行为不相同。

我会使用cout,并重载operator << (ostream&, const CustomString&)

不要这样做:

我说过你不能,以便携的方式。对于这样的类

class CustomString
{
   char* str;
   //...
};

这可能会起作用,因为类在内存中是如何表示的。但是,这仍然是一种未定义的行为。

printf定义为

int printf(char const *fmt, ...)

将类或结构传递给。。。参数列表有未定义的行为,可能会工作或崩溃,或者只是做一些随机的事情(我已经看到了所有3个),这取决于类和编译器。

printf(str)

需要一个char*,编译器发现你有一个合适的强制转换运算符,所以它会调用它。注意,这很不可靠,因为你不知道str中是否有%。

所以,你确实想要printf("%s", str),但正如你所说,这不起作用。有些编译器会给你一个警告(尽管在我看来,gcc产生的"警告:这将崩溃"并没有经过深思熟虑),所以你必须强制将其转换为字符串。所以,你最好的解决方案是自己显式铸造,

printf("%s", static_cast<char const *>(str));

我不确定你得到的所有例子需要多少代码,因为大多数例子都涉及到从自定义字符串中构造一个std::字符串,然后输出它,然后删除std::string。

您必须使用printf("%sn", str.c_str());%s需要一个char数组,而您给了它一个不同的CustomString对象。您必须通过调用c_str()函数从字符串中获取char数组。