C++字符串和指针

C++ strings and pointers

本文关键字:指针 字符串 C++      更新时间:2023-10-16

我正在学习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的访问冲突"。

有人能提出一个解决方案吗?仍然使用指针和字符串而不是字符数组(我已经想好了怎么做)?

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

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

值得补充的是,在这种情况下使用指针是毫无意义的:标准C++库中的字符串对象为堆中的字符串分配数据;字符串通常只不过是一对指针。

我认为,您根本不想使用pointers。您可以在没有指针的情况下使用strings

#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;

它看起来像这样:

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

但实际上没有理由这么做,只需在堆栈上定义一个普通的字符串变量即可。

您会收到错误,因为您使用字符串作为指针,而没有初始化它们。正确的方法是:

#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引用,如果您愿意的话)传递。

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

此处设置空指针

string * firstName=nullptr;

然后在这里取消引用

getline(cin,*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;
}

阅读c编程的10条戒律。对于今天的开发者来说,有些或多或少已经过时了,但有些仍然很重要,比如第二个:

你不应该遵循空指针,因为混乱和疯狂在它的尽头等着你。

这就是你在这里所做的。您的指针指向任何位置(请参阅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

由于您使用的是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并不是您想要的:您需要分配您想要使用的资源。

请注意,在这些简单的情况下使用指针,无论是在语法方面还是在错误方面,都是在自食其果

EDIT我更正了代码(忘记的括号和main最后一行的*),它成功地编译并运行在GCC 4.7上。