【问题标题】:How to fill up char with string after allocation?分配后如何用字符串填充字符?
【发布时间】:2013-04-08 17:53:32
【问题描述】:

我有这个结构:

struct student {
  int id;
  string name;
  string surname;
};

我需要做的是用这个声明来做函数:

char* surname_name (student Student)

它将格式化我输入的每个学生的格式,如“姓,名”,它会带回指向它的指针。

到目前为止,我所做的是:

char* surname_name (student Student){
    char *pointer= (char*) malloc (sizeof(char)*(Student.name.length + Student.surname.length + 2)); // + 2 because of space and comma

    string::iterator it;
    int i=0;

    for (it= Student.surname.begin(); it != Student.surname.end(); it++){
        (*pointer)[i] = it; // here it gives me error
    }

    ... // here still should be added code for comma, space and name
    return pointer;
}

无论如何我都做不到,因为在任务中函数需要有这个声明。如何正确地做到这一点?

【问题讨论】:

  • 你真的需要char*吗? std::string 不是更好吗?如果您需要这样,我建议将char* 作为参数,让用户将自己分配的缓冲区传递给。
  • 是的,我肯定会立即使用它,但我不能。需要使用这个,因为稍后我需要制作其他函数,它将这个函数作为参数,所以我不能修改声明。
  • 你不能返回一个std::string,然后使用c_str成员函数将它作为char*来获取吗?
  • 您可以在一个字符串中进行连接,然后您可以只 malloc 一些内存,将字符串 memcopy 到其中,然后返回。这样会容易得多。

标签: c++ pointers memory-management character


【解决方案1】:

这应该可以解决问题:

char * surname_name (student Student){
    return strdup((Student.surname + ", " + Student.name).c_str());
}

【讨论】:

  • 我收到此错误:错误 C4996:'strdup':不推荐使用此项目的 POSIX 名称。而是使用符合 ISO C++ 的名称:_strdup。有关详细信息,请参阅在线帮助。
  • 在 Windows 平台上使用 _strdup 代替 strdup
  • 它现在可以工作了:)。 @Joel,当我用 return 取回指针时,我应该什么时候释放它?
  • 如果你在某个时候不释放它,你就会发生内存泄漏。 strdup 用 malloc 分配指针。
【解决方案2】:
(*pointer)[i] = it;

应该是

*(pointer+i) = *it; //assigning the current char to correct position

你也应该适当增加i

您也可以使用std::string 来实现,它可以进行简单的连接。

【讨论】:

  • 我做了这个,“i”下划线表示错误,写着:“错误:表达式必须具有指向对象的指针类型”
【解决方案3】:

我更喜欢使用std::string::c_str:

string surname_name (const student &Student)
{
    return Student.name + " " + Student.surname;
}

// ...

do_something( surname_name(student).c_str() );

 

如果你真的想返回一个指针,你可以这样做:

char *surname_name (const student &Student)
{
    string s = Student.name + " " + Student.surname;
    char *p = new char [s.length()+1];
    strcpy(p, s.c_str());
    return p;
}

不要忘记delete返回的指针。

【讨论】:

  • 为了让代码可读,多花一份拷贝是值得的。
  • 另外,由于 RVO,它没有额外的副本。
  • 可悲的是,确实如此。您在创建新字符串后复制了它,然后显式完成了 strcpy.大多数字符串实现不是写时复制。 RVO 仅适用于最后一条语句,在创建临时时。在这种情况下,您将返回一个指针,因此它不适用。可以直接复制到字符数组而不是创建字符串,但这更容易出错且更难维护。
  • 啊哈,您说的是基于指针的解决方案。是的,它有额外的副本。同意。
猜你喜欢
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
  • 2019-06-12
相关资源
最近更新 更多