C++ fprintf与函数返回的字符有问题

C++ fprintf与函数返回的字符有问题,c++,char,printf,C++,Char,Printf,我有两个问题。这两种方法都可以通过以下简单代码来说明(用g++-Wall-O2-std=c++14编译): #包括 使用名称空间std; 常量字符*printi(常量无符号长(&i){ 返回到_string(i)).c_str(); } int main(){ 无符号长i1=1;无符号长i2=2; fprintf(stderr,“%s%s\n”、printi(i1)、printi(i2)); } 问题1-它打印“11”,而它应该打印“12” 问题2-有时它根本不打印数字,而是打印一些奇怪的字符

我有两个问题。这两种方法都可以通过以下简单代码来说明(用g++-Wall-O2-std=c++14编译):

#包括
使用名称空间std;
常量字符*printi(常量无符号长(&i){
返回到_string(i)).c_str();
}
int main(){
无符号长i1=1;无符号长i2=2;
fprintf(stderr,“%s%s\n”、printi(i1)、printi(i2));
}
问题1-它打印“11”,而它应该打印“12”


问题2-有时它根本不打印数字,而是打印一些奇怪的字符。

注意
std::to_string()
返回一个
std::string
。此
std::string
仅存在于
printi()
函数范围内,这意味着当您退出函数时(当您
return
时),将调用此
std::string
的析构函数,并且您返回的地址(由
c_str()
返回的值)不再指向有效内存。您的代码有未定义的行为,因为您不知道它现在指向哪个数据

为了解决这个问题,您可以让
printi()
返回一个
std::string
,它将在
返回时深入复制到调用方,然后调用方可以根据需要使用
c_str()

#include <string>
using namespace std;

string printi(const unsigned long &i) {
    return to_string(i);
}

int main() {    
    unsigned long i1 = 1; unsigned long i2 = 2;
    fprintf(stderr, "%s%s\n", printi(i1).c_str(), printi(i2).c_str());
}
#包括
使用名称空间std;
字符串打印i(常量无符号长(&i){
返回到_字符串(i);
}
int main(){
无符号长i1=1;无符号长i2=2;
fprintf(stderr,“%s%s\n”,printi(i1.c_str(),printi(i2.c_str());
}

注意
std::to_string()
返回一个
std::string
。此
std::string
仅存在于
printi()
函数范围内,这意味着当您退出函数时(当您
return
时),将调用此
std::string
的析构函数,并且您返回的地址(由
c_str()
返回的值)不再指向有效内存。您的代码有未定义的行为,因为您不知道它现在指向哪个数据

为了解决这个问题,您可以让
printi()
返回一个
std::string
,它将在
返回时深入复制到调用方,然后调用方可以根据需要使用
c_str()

#include <string>
using namespace std;

string printi(const unsigned long &i) {
    return to_string(i);
}

int main() {    
    unsigned long i1 = 1; unsigned long i2 = 2;
    fprintf(stderr, "%s%s\n", printi(i1).c_str(), printi(i2).c_str());
}
#包括
使用名称空间std;
字符串打印i(常量无符号长(&i){
返回到_字符串(i);
}
int main(){
无符号长i1=1;无符号长i2=2;
fprintf(stderr,“%s%s\n”,printi(i1.c_str(),printi(i2.c_str());
}


有趣的是,当我运行此代码时,我得到22作为输出。为什么要打印到
stderr
而不是
stdout
?您返回的是一个临时=坏消息。如果我不能使用函数返回的值,我该如何工作(我需要将该字符串放入fprintf…(整个代码只是一个更大的东西的抽象,这应该是一个调试信息,这就是为什么它是stderr)@ Jecke:你写C还是C++?使用<代码> STD::String ,使用<代码> STD::CURR < /Cord> >如果你正在写C++,我在C++中写,但是我使用FPrTNF,因为它更方便。我可以有<代码> fPrtuf(“Balh %Balh %Bua%S\n”,a,b,c)
而不是
cerr有趣的是,当我运行此代码时,我得到22作为我的输出。为什么你要打印到
stderr而不是
stdout
?你返回了一个临时=坏消息。如果我不能使用函数返回的值,我该如何工作?:(我需要将该字符串放入fprintf。。。(整个代码只是一个更大的东西的抽象,这就是一个调试信息,这就是为什么它是STDRR):JECKE:你写C还是C++?使用一个<代码> STD::String ,使用<代码> STD::CURR < /Cord> >如果你正在写C++,我在用C++编写,但是我使用FPrTNF,因为它更方便。我可以有<代码> fPrtuf(“blah%s blah%lu blah%s\n”,a,b,c)
而不是
cerr True.Fixed.Thank.Hmm…所以如果我创建一个函数int return5(){short a=5;return a;},我不能期望这个cout“为了修复它,可以返回对std::string的引用。”“--听起来你是在建议用悬挂引用替换悬挂指针。如果不是,我不确定你在这里的建议是什么。当你返回一个对象(char*,int)时,这实际上会起作用。”然后它被复制,对于int,它将复制它的数据,对于char*它将复制它的地址。如果你返回std::string,它也将复制它的数据,但是当你退出作用域时,会调用析构函数,现在c_str字符串的地址不再有效,内存被清理了!现在你手里拿着无效的地址,试图打印出来。@Jecke:如果你创建了这样一个函数,更好的类比是:
int*return5(){int A=5;return&A;}
——在这种情况下,你不能保证
不能为True.Fixed.Thank.Hmm.。所以如果我创建了一个函数int return5(){short A=5;return A;},我不能期望它为True.Fixed.Thank.Hmm“为了修复它,您可以返回对std::string的引用”--听起来您建议用悬挂引用替换悬挂指针。如果不是,我不确定您在这里的建议。当您返回对象(char*,int)时,这实际上会起作用然后它被复制,对于int,它将复制它的数据,对于char*它将复制它的地址。如果你返回std::string,它也将复制它的数据,但是当你退出作用域时,会调用析构函数,现在c_str字符串的地址不再有效,内存被清理了!现在你手里拿着无效的地址,试图打印出来。@Jecke:如果你创建了这样一个函数,更好的类比是:
int*return5(){int A=5;return&A;}
——在这种情况下,你不能保证
可以