0

I have strings of the following format: "name.bag.csv" I would like to remove the ".bag" from the string. This is an example of the code that I am trying to run:

csv_file_name = "loololololool.bag.csv";
csv_file_name.erase(csv_file_name.end()-8, 4);
std::cout << csv_file_name << std::endl;

But I get an error on the second line:

 no matching function for call to ‘std::__cxx11::basic_string<char>::erase(__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >, int)’
         csv_file_name.erase(csv_file_name.end()-8, 4);

It seems to only take one argument. However if I do:

csv_file_name = "loololololool.bag.csv";
csv_file_name.erase(13, 4);
std::cout << csv_file_name << std::endl;

it seems to work fine. Also when I execute

csv_file_name = "loololololool.bag.csv";
csv_file_name.erase(csv_file_name.end()-8);
std::cout << csv_file_name << std::endl;

It deletes the single character as it should. How can this happen? The csv_file_name.end()-8 must be working as it deletes the single character. And taking two arguments should be working as well. But the combination doesn't? Please help!

Martijn
  • 11
  • 3
  • 2
    Try [reading the manual](https://en.cppreference.com/w/cpp/string/basic_string/erase), it's all explained there. – john May 01 '20 at 08:20

3 Answers3

3

You are mixing up iterators and indexes.

  • string.erase(iter) // delete the character pointed to by the iterator

  • string.erase(iter1, iter2) // delete the characters between the two iterators

  • string.erase(index, count) // delete count characters starting at index

csv_file_name.end()-8 is an iterator and there is no version of erase that takes an iterator and an index or count.

Instead of

csv_file_name.erase(csv_file_name.end()-8, 4);

I think you meant

csv_file_name.erase(csv_file_name.size()-8, 4);

But really you should be able to read documentation and figure this stuff out for yourself. You'll be a lot more efficient that way.

john
  • 85,011
  • 4
  • 57
  • 81
0

You are mixing up the singatures of std::string::erase. There is overloads that work with one or two integer positions, and another set of overloads that works with one or two iterators, see here.

What you are trying to do is call erase with a signature (iterator, integer). This overload simply does not exist.

edit too late :)

geo
  • 435
  • 3
  • 13
0
#include <bits/stdc++.h>
using namespace std; 
/*
  I have used this for this demonstration. However, it is
  not recommended to write this in larger projects. Please refer this https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice 
*/
int main() {
    //I have taken the position of the first dot. This is the position
    //from where I am deleting 4 characters including the first dot.
    //This holds true given the structure of the string is as below.
    //Please note that as long as the string follows this structure
    //<any number of characters>.bag<any number of characters> this will pass.
    string s1 = "loololololool.bag.csv";
    string s2 = "loololololool.bag.csv";

    cout << "Demo 1 Analysis \n";
    //Please consult this link http://www.cplusplus.com/reference/string/string/erase/
    //Demo signature #1 string& erase (size_t pos = 0, size_t len = npos);-------
    int posFirstDot1 = s1.find('.');
    string result1 = s1.erase(posFirstDot1, 4);
    cout << s1 << endl;
    cout << "Address of result1 : " << &result1 << " and address of s1 : " << &s1 << endl;
    //Note that result1 and s1 are same but are present at different addresses. Thats Subtle :)
    //----------------------------------

    cout << "Demo 2 Analysis\n";
    //Demo signature #3 iterator  erase (const_iterator first, const_iterator last);
    int posFirstDot2 = s2.find('.');
    //get an iterator with s.begin() and posFirstDot3
    auto itFirstDot2 = next(s2.begin(), posFirstDot2);
    //we want to delete the next 4 characters starting from position of first dot
    auto itLastCharacterToBeRemoved = next(itFirstDot2, 4);
    auto result3 = s2.erase(itFirstDot2, itLastCharacterToBeRemoved);
    cout << s2 << endl;
    return 0;
}
punter147
  • 302
  • 2
  • 7