STL std :: remove(...)在我的主程序中不起作用 [英] STL std::remove(…) doesn't work in my main program

查看:130
本文介绍了STL std :: remove(...)在我的主程序中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从字符串中删除所有空格,因此我编写了一个小的辅助函数来实现.

在基本程序中进行测试时,一切正常.在我更复杂的项目中,它会发生故障.此外,当我键入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 function remove 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 the str.end() iterator of the original string to pass it to str.erase. So, your code will be fixed is your replace your like using remove and erase 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 [

—SA


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

—SA


这篇关于STL std :: remove(...)在我的主程序中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆