我正在尝试创建一个简单的(模块化的)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”]
所以我想知道如果未在两行之间分配或操纵用户名,那么该用户名的值是如何变化的。
答案 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';
}
(另外,这一点不太重要,因为领先_printOut
。See 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)
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