C++字符串和指针

13

我正在学习C++,目前正在处理字符串和指针。

我在跟随一本练习书的内容,其中一个问题中我已经写出了下面的代码:

#include <iostream>
#include <string>

using namespace std;

int main(void){
    string * firstName=nullptr;
    string * lastName=nullptr;
    string * displayName=nullptr;

    cout << "Enter your first name: " << endl;
    getline(cin,*firstName);

    cout << "Enter your last name: " << endl;
    getline(cin,*lastName);

    displayName=new string;
    *displayName= *lastName + ", " + *firstName;

    cout << "Here's the information in a single string: " << displayName;
    cin.get();
    return 0;
}

为了更多地使用指针,我尝试将其与字符串混合使用,并因此使解决方案变得更加复杂。运行时我收到一个“未处理的异常:访问违例读取位置 xxxxxxxxx”。

请问有人可以建议一个解决方案,仍然使用指针和字符串,而不是 char 数组(我已经知道如何做到这一点)吗?


3
你没有分配字符串,然后将一个空指针传递给getline()函数...只需将所有的string *x = nullptr;'更改为string x;或者在传递给getline()之前像displayName一样分配这些字符串。 - Yaniro
1
如果你刚开始“学习C ++”,就不应该接触原始指针。它们是C ++中困难、高级、专业化的部分,对于大多数“正常”的编程活动来说是不需要的。 - Kerrek SB
这个 视频片段 在我困惑指针的时候总是非常鼓舞人心;-) - Frank Bollack
2
如果这本书真的建议你在简单的本地变量中使用std::strings的原始指针,请把它扔掉。 - PlasmaHH
2
@KerrekSB:“你不应该接近原始指针。”我建议相反。从指针开始,以C风格编程,并远离高级概念,如字符串和STL。几个月后,切换到STL。“它们是困难的、高级的”,它们是C++的基本部分(“基本素养”水平),你必须学会它们。如果不理解它们,你将无法实现自己的容器,也不会真正理解STL的工作原理。一个不能实现链表的人不能被称为程序员,你知道的... - SigTerm
7个回答

18

这是因为您在使用对象之前没有进行分配

string * firstName = new string();
//...
delete firstName;

值得一提的是,在这种情况下使用指针是毫无意义的:标准C++库中的字符串对象将为字符串分配堆数据;而且字符串通常不会比一对指针更复杂。


5

我认为,你根本不需要使用指针。你可以在不使用指针的情况下处理字符串。

#include <iostream>
#include <string>

using namespace std;

int main(void){
  string firstName;
  string lastName;
  string displayName;

  cout << "Enter your first name: " << endl;
  getline(cin,firstName);

  cout << "Enter your last name: " << endl;
  getline(cin,lastName);

  displayName= lastName + ", " + firstName;

  cout << "Here's the information in a single string: " << displayName;
  cin.get();
  return 0;
}

否则,如果您需要指针,则必须为变量分配内存:
  cout << "Enter your first name: " << endl;
  firstName = new string();
  getline(cin,*firstName);

使用解引用运算符(*)打印结果:

cout << "Here's the information in a single string: " << *displayName;

2
它看起来会像这样:

int main()
{
    std::string* s = new std::string;
    std::getline(std::cin, *s);
    std::cout << *s;
    delete s;
}

但其实没有必要这样做,只需在堆栈上定义一个普通的字符串变量即可。


2

您出现错误的原因是使用字符串作为指针,并且没有对它们进行初始化。正确的做法是:

#include <iostream>
#include <string>

using namespace std;

int main(void){
    string firstName;
    string lastName;
    string displayName;

    cout << "Enter your first name: " << endl;
    cin >> firstName;

    cout << "Enter your last name: " << endl;
    cin >> lastName;

    displayName = firstname + ' ' + lastName;


    cout << "Here's the information in a single string: " << displayName << endl;
    return 0;
}

您可以使用指针来操作字符串,但它们应该作为本地对象使用并传递引用(或const引用,如果您希望这样做)。


1

访问冲突是因为您正在取消引用空指针。

空指针在此处设置

string * firstName=nullptr;

然后在这里取消引用

getline(cin,*firstName)

你需要将 firstname “指向” 某个东西(在这种情况下是一个字符串)。 以下是一个没有异常的修改版本。

int main(void){
    string * firstName= new string();
    string * lastName=new string();
    string * displayName=new string();

    cout << "Enter your first name: " << endl;
    getline(cin,*firstName);

    cout << "Enter your last name: " << endl;
    getline(cin,*lastName);

    //displayName=new string;
    *displayName= *lastName + ", " + *firstName;

    cout << "Here's the information in a single string: " << displayName->c_str();
    cin.get();
    return 0;
}

嗨,这仍然给我一个未处理的异常。我将关闭此方法并坚持简单的路线。谢谢。 - Dan
刚刚发现在我修复程序后,是我自己导致了错误。非常感谢您的帮助。 - Dan

0

既然你正在使用nullptr,我猜一个完整的C++11解决方案同样适用:

#include <iostream>
#include <memory>
#include <string>

using namespace std;

int main(void){
    unique_ptr<string> firstName(new string());
    unique_ptr<string> lastName(new string());
    unique_ptr<string> displayName(new string());

    cout << "Enter your first name: " << endl;
    getline(cin,*firstName);

    cout << "Enter your last name: " << endl;
    getline(cin,*lastName);

    *displayName= *lastName + ", " + *firstName;

    cout << "Here's the information in a single string: " << *displayName;
}

当然,使用nullptr并不是你想要的:你需要分配你想要使用的资源。

请注意,在这些简单情况下使用指针会让你自己陷入困境,无论是语法还是错误方面。

编辑我已经更正了代码(遗漏的括号和main中最后一行的*),它在GCC 4.7上成功编译和运行。


谢谢你。我仍然从xstring文件中得到未处理的异常错误。你认为Visual Studio有问题吗?我很感激,我不应该这样做,我会放弃它,坚持使用字符串的基础知识。 - Dan

0

阅读 C编程的十诫。其中一些已经过时,不再适用于今天的开发人员,但有些仍然很重要,比如第二个:

不可追踪空指针,因为在其末端等待着混乱和疯狂。

这实际上就是你在这里做的事情。你的指针指向无处(请参见对std::nullptr的赋值)。

要纠正这个问题,你必须将正确类/结构的新对象分配给指针。此外,不要忘记稍后删除它:

std::string *myString = new std::string(); // create an object and assign it's address to the pointer

// do something with it... (this part has been right)

delete myString; // free the memory used by the object

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接