我有以下代码:
#include <iostream>
using namespace std;
void func(char * aString)
{
char * tmpStr= new char[100];
cin.getline(tmpStr,100);
delete [] aString;
aString = tmpStr;
}
int main()
{
char * str= new char[100];
cin.getline(str,100);
cout<< str <<endl;
func(str);
cout<< str <<endl;
return 0;
}
为什么第二个cout
不打印第二个输入字符串?如何更改此代码才能使用它?
答案 0 :(得分:12)
正如GregS所说,简单的回答是使用引用声明你的函数:
void func(char *&aString)
然而,这并不是最好的解决方案。在C ++中,您通常会避免使用简单数组并使用容器。
#include <iostream>
#include <string>
void func(std::string &s)
{
std::getline(std::cin, s);
}
int main()
{
std::string str;
func(str);
std::cout << str << std::endl;
return 0;
}
答案 1 :(得分:6)
因为第二个cout
将打印str
指向的内容。主函数中的str
指针在调用func
之前和之后将具有相同的值。
实际上,在func
函数中,您正在更改aString
变量的值。但这是另一个变量,而不是主要的str
。
如果您希望更改str
的值,则必须通过引用或指针将其传递给func
。 (注意你写的是用指针传递字符。我的意思是你必须通过指针传递指针:void func(char **str_ptr)
或引用void func(char *&str_ref)
)
如果你真的在做C ++,你应该使用std :: string而不是旧的C字符串。
通过指针传递指针的示例:
func(char ** aString)
{
char * tmpStr= new char[100];
cin.getline(tmpStr,100);
delete [] *aString;
*aString = tmpStr;
}
另外你应该这样称呼:func(&str);
答案 2 :(得分:2)
当从main()调用func()时,str指针的值被传递给函数(这是通过将它的值复制到堆栈来完成的)
调用func()时存储在堆栈上的值成为func()中的局部变量aString。您可以修改此值,但只要func()返回它的所有局部变量就会被丢弃。 aString 的值不会被复制回str 。
要使您的代码正常工作,您必须:
答案 3 :(得分:2)
将func更改为
void func(char * aString)
{
cin.getline(aString,100);
}
它起作用,至少它对我有用。
答案 4 :(得分:1)
如果您的目标是从键盘上实际读取一行,请执行以下操作:
std::string foo;
std::getline(std::cin, foo);
否则,当您将指针传递给函数时,指针按值传递。这意味着您无法在函数内更改指针本身,但您可以更改它指向的对象。在C ++中,您可以按如下方式执行此操作:
void bar(std::string & s) {
std::getline(std::cin, s);
}
// in calling code
std::string foo;
bar(foo);
这将对字符串的引用传递给函数。该函数现在可以更改字符串的内容。
如果你想编写一个分配一些内存来存储结果的函数,可以这样做:
boost::shared_array<char> foo() {
boost::shared_array<char> result(new char[100]);
std::cin.getline(result.get(), 100);
return result;
}
答案 5 :(得分:1)
指针按值传递。是的,您可以更改指针所指向的内容,但退出该函数时会保留旧地址本身。因此,“aString = tmpStr”;变得无用,“char * tmpStr = new char [100];”造成内存泄漏。您需要通过引用传递指针:
void func(char*& aString)
{
char * tmpStr= new char[100];
cin.getline(tmpStr,100);
delete [] aString;
aString = tmpStr;
}
答案 6 :(得分:0)
赋值函数中的参数aString对main()
中的str没有影响 你可以尝试 return aString
并在主
str = funct(str);
但事实上,没有理由将str传递给函数。
答案 7 :(得分:0)
行aString = tmpStr
只是将astring
(即地址/指针)的值更改为另一个值(即另一个地址/指针),但不是{{1}指向的内容。 1}}。
您可以尝试将签名更改为:
aString
将void func(char ** aString)
的最后两行更改为:
func
因此,最后一行会导致程序将delete [] *aString;
*aString = tmpStr;
指向的内存中存储的地址更改为新分配的地址(aString
)。 (我知道,这令人难以置信。)
然后通过
调用它tmpStr
答案 8 :(得分:0)
您需要传递str作为参考。
答案 9 :(得分:0)
#include <iostream>
void func(std::istream& is, std::string& aString)
{
std::getline(is, aString);
}
int main()
{
std::string str;
std::getline(std::cin, str);
if(std::cin)
std::cout<< str << '\n';
std::string str;
func(std::cin, str);
if(std::cin)
std::cout<< str << '\n';
return 0;
}
答案 10 :(得分:0)
传递给func()的指针aString
表示您可以读取和写入字符串str
的位置(在哪个地址)。然后当你说aString = tempStr
时,你用一个新值(str
指向的字符串的地址替换它的原始值(tempStr
指向的字符串的地址) )。这不会导致str
指向与tempStr
相同的位置。
想象一下,我和朋友的家庭住址给你一张纸。然后你把它刮掉并写上你兄弟(住在伦敦)的地址。如果我决定去拜访我的朋友,我将不会前往伦敦,即使你可能有一张纸上写着“保罗的朋友:123伦敦”。
要让main
打印出您在func
()中输入的字符串,您可以将输入字符串复制到aString(将您的兄弟移动到我朋友的家中),或者传递指针或引用str(让我给你我的地址簿,这样你就可以把我朋友的条目改为伦敦)。无论哪种方式,下次我访问“我朋友的家”时,你的兄弟都会在那里。