C ++指针问题

时间:2013-05-17 08:53:51

标签: c++ pointers

我正在尝试创建一个简单的(模块化的)c ++程序,该程序读取用户输入并将其吐出。

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

void _printOut(char * output)
{
    cout << output << endl;
}
char * readUserInput()
{
    char userInput[256];
    cin >> userInput;
    return userInput;
}

int _tmain(int argc, _TCHAR* argv[])
{
    _printOut("Enter your name: ");
    char * userName = readUserInput();
    _printOut("Hello");
    _printOut(userName);
    system("pause");
    return 0;
}

输入您的姓名: AAAA 你好     ╠╠╠╠╠╠╠╠ 按任意键继续 。 。

如果我在readUserInput函数中打印出userInput变量,它会打印出输入的内容。但是,尝试在_tmain函数中将userInput变量存储打印为userName会导致打印出一个难以理解的字符序列。即。 ╠╠╠╠╠╠╠╠。 根据我的最佳猜测,这可能是由指针问题引起的,但据我所知,我正在引用所有内容。

调试此代码: 在这一行:_printOut(“你好”);在方法中:_tmain [userName =“abcdefg”] 在这一行:_printOut(userName);在方法_tmain [userName =“†UX”]

所以我想知道如果未在两行之间分配或操纵用户名,那么该用户名的值是如何变化的。

5 个答案:

答案 0 :(得分:4)

char * readUserInput()
{
    char userInput[256];
    cin >> userInput;
    return userInput;
}

char userInput[256];数组仅在函数调用期间存在。一旦你到达函数的底部它就不再存在了,你返回一个指向一些垃圾内存的指针。 这称为local scope

无论如何,如果某人有一个长名称(超过255个字符),该怎么办。

考虑使用std::string,这将解决这两个问题。

std::string readUserInput()
{
    std::string inp;
    std::cin >> inp;
    return inp;
}

void printOut (const std::string& toPrint)
{
    std::cout << toPrint << '\n';
}

(另外,这一点不太重要,因为领先_printOutSee here,因此在此上下文中不允许使用名称_,但如果它可能超过您的头你是初学者。)

修改更好的方法是使用std::getline一次将整行读入std::string。但是,由于他们处理空格的方式,特别是'\n'换行符,getline(...)cin>>...不能很好地融合在一起。通常最好选择一个并在整个程序中坚持使用它。以下是readUserInput()的外观:

std::string readUserInput()
{
    std::string line;
    std::getline(std::cin, line);

    return line;
}

这样,如果用户输入包含空格的名称(例如"BoB T. Fish"),您将读取整个名称,而不仅仅是"BoB"(然后在下次阅读时将其余内容与您混淆)。

cin>>...getline混合起来的原因可能是cin>>...将尽可能多地读取空格,然后将其余部分留空。因此除了mayb发出某人的姓氏,如果他们输入一个没有空格的名字,它只会在输入流上留下最后一个换行符。然后,当你来getline时,你没有得到用户输入的 next 行。你得到了留下的空行。如果您再次使用cin>>,则会忽略换行符。  例如考虑这个用户输入:

Hello\n
World\n

如果您使用cin>>进行首次阅读,则会在您的计划中获得"Hello",然后留下

\n
World\n

如果您使用getline进行第二次阅读,则会在您的计划中获得"",然后留下

World\n

答案 1 :(得分:2)

当readUserInput退出时,

char userInput[256];将被销毁,因此返回的指针无效。

改为使用std::string

或动态分配变量,或将自动变量作为参数传递。

答案 2 :(得分:1)

userInput变量一旦超出范围就会被销毁。

局部变量存储在堆栈中。一旦函数执行完成,变量就会被破坏。

您需要使用动态分配的char指针(堆上的存储)或std :: string

答案 3 :(得分:0)

这里的问题是一个范围问题:

char userInput[256];定义一个仅在其自己的范围内有效的局部变量(在{}括号的ist集之间)。

你实际上返回一个有效的指针,一旦你离开函数就会失效,因为它被释放了。

您违反了基本规则:永远不会返回指向本地(非静态)变量的指针。

要解决此问题,请使userInput静态或返回一个新字符串(使用new每次调用创建一个新字符串)或使用可复制对象而不是指针(如std::string)。

答案 4 :(得分:0)

您正在使用指向已超出范围的缓冲区(In stack)的指针。

试试这个:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

void _printOut(char * output)
{
    cout << output << endl;
}
char * readUserInput()
{
    //Allocate in Heap, instead of stack
    char* userInput = new char[256];
    cin >> userInput;
    return userInput;
}

int main(int argc, char* argv[])
{
    _printOut("Enter your name: ");
    char * userName = readUserInput();
    _printOut("Hello");
    _printOut(userName);
    system("pause");
    return 0;
}

更好的方法是使用 std :: string