STL std :: remove(...)在我的主程序中不起作用 [英] STL std::remove(…) doesn't work in my main program
问题描述
我正在尝试从字符串中删除所有空格,因此我编写了一个小的辅助函数来实现.
在基本程序中进行测试时,一切正常.在我更复杂的项目中,它会发生故障.此外,当我键入std::re
时,自动完成功能会提供正确的replace
,但是一旦我键入(
,签名就会变成int replace( const char* _Filename )
.
我已经尝试根据此问题 [ ^ ]但没有任何变化:
I am trying to remove all spaces from a string, therefore I wrote a small helper function to do it.
When tested in a basic program, everything works fine. In my more complex project it malfunctions. Furthermore, when I type std::re
autocomplete offers proper replace
but as soon as I type (
the signature turns into int replace( const char* _Filename )
.
I have tried rewriting helper function according to this question[^] but nothing changes:
// helper method for removing spaces
const char* removeSpace( std::string &str )
{
str.erase( std::remove( str.begin(), str.end(), ' ' ), str.end() );
return str.c_str();
}
您能帮我解决这个问题吗?
以下是测试.cpp
文件的内容:
Can you please help me to fix this problem?
Here is the content of a test .cpp
file:
#include <iostream>
#include <algorithm>
#include <string>
#include <fstream>
// helper method for removing spaces
const char* removeSpace( std::string &str )
{
std::remove( str.begin(), str.end(), ' ' );
return str.c_str();
}
int main()
{
std::string str = " jkl ll ";
std::cout << removeSpace( str ) << std::endl;
return 0;
}
我要从主项目发布.cpp
和.h
文件的内容:
.h
I am posting the content of the .cpp
and .h
files from the main project:
.h
#ifndef _Person_h_
#define _Person_h_
#include <iostream>
#include <list> // std::list
#include <fstream> // std::ifstream, std::ofstream
#include <string> // std::string
#include <algorithm> // std::remove, std::remove_if
class Lista
{
private:
struct Person
{
// data
std::string dateOfBirth;
// constructor
Person( const char *date )
{
dateOfBirth = date;
}
// destructor
~Person()
{
dateOfBirth.clear();
}
};
// linked list of Person. Person is populated with data from delimited file
std::list<Person> persons;
public:
// helper method for removing spaces
const char* removeSpace( std::string &str )
{
std::remove( str.begin(), str.end(), ' ' );
return str.c_str();
}
// method for inserting data from a file
Lista& insertPerson( const char *inputFile,
const int maxTextLength = 100,
const char delimiter = ',' )
{
// open file
std::ifstream g;
g.open(inputFile);
if( g.is_open() )
{
while( !g.eof() )
{
// temporary string
std::string date;
// get data from file
g.getline( &date[0], maxTextLength, delimiter );
// initialize temporary structure with data from file
Person p( removeSpace( date ) );
// insert it into linked list
persons.push_back(p);
//cleanup
date.clear();
}
g.close();
}
return *this;
}
// other stuff
};
#endif
.cpp
.cpp
#include "Person.h"
int main()
{
Lista p;
p.insertPerson( "pipe.txt", 100, '|' );
std::cout << p << std::endl;
return 0;
}
推荐答案
您应正确使用函数remove
函数的返回值.它将迭代器返回到最后一个未被删除的元素之后的元素:
http://www.cplusplus.com/reference/algorithm/remove [
You should properly use the return from the functionremove
function. It returns an iterator to the element that follows the last element not removed:
http://www.cplusplus.com/reference/algorithm/remove[^].
Then you need to use the iterator obtained and thestr.end()
iterator of the original string to pass it tostr.erase
. So, your code will be fixed is your replace your like usingremove
anderase
with the following line:
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
这是在此处说明的已知的删除擦除习惯用法的使用: http://en.wikipedia .org/wiki/Erase-remove_idiom [ ^ ].
另请参见: http://en.cppreference.com/w/cpp/algorithm/remove [ ^ ].
但是,这还不是全部.更大的问题(即代码的设计)是这样的:使用您的方法,您将从 std::string
跳转到字符串的空终止表示,然后返回,这完全是无效的.由于此演示文稿会忘记"字符串的长度,因此以空值结尾的字符串会增加CPU使用率,因此每次使用时,代码都必须不断地由终止符找到它(例如,初始化另一个std::string
加上它,这增加了O(N)的时间复杂度的冗余运算.一旦得到std::string
,最好还是坚持使用它.以此方式更改其签名:
This is the use of the known erase-remove idiom explained here: http://en.wikipedia.org/wiki/Erase-remove_idiom[^].
See also: http://en.cppreference.com/w/cpp/algorithm/remove[^].
However, this is not all. Your problem with the bigger picture — design of your code — is this: with your approach, you would be jumping from std::string
to the null-terminated representation of strings and back, which is utterly inefficient. The null-terminated strings adds CPU usage due to the fact that this presentation "forgets" the length of the string, so the code will have to find it by the terminator over and over each time you use it (for example, initialize another std::string
with it. This adds a redundant operation of the time complexity of O(N). Once you got an std::string
, you should better stay with it. Your function will be more useful if you change its signature in this way:
std::string RemoveSpace(std::string &str)
// or, optionally, return const std::string
{
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
return str;
}
另请参见:
http://en.wikipedia.org/wiki/Time_complexity [ http://en.wikipedia.org/wiki/Big_O_notation [ http://en.wikipedia.org/wiki/Computational_complexity_theory [
See also:
http://en.wikipedia.org/wiki/Time_complexity[^],
http://en.wikipedia.org/wiki/Big_O_notation[^],
http://en.wikipedia.org/wiki/Computational_complexity_theory[^].
The first comment to the question by Wes Aday actually presented a correct answer (if you remove the text after '';''). I just did not pay attention for it because, when this comment appeared, I was editing this answer in response to an OP''s follow-up question
这篇关于STL std :: remove(...)在我的主程序中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!