[Rcpp-devel] Bug: replace_last()
Kevin Ushey
kevinushey at gmail.com
Mon May 16 20:04:51 CEST 2016
Thanks -- it looks to me like there is something more fundamentally
wrong with the 'replace_first' and 'replace_last' methods; ie, I don't
think we want to be using 'find_first_of' and 'find_last_of'
functions.
Ie, when writing
string.replace_first("foo", "bar");
I imagine we want to replace the first occurrence of 'foo' with 'bar',
and not the first discovered character of 'f' and 'o'.
A simple repro for the bogus behavior:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
String replace() {
String foo("abba");
return foo.replace_first("ba", "BA");
}
/*** R
replace()
*/
gives
> replace()
[1] "BAba"
which is I doubt what anyone would expect.
On Sun, May 8, 2016 at 6:14 AM, 津田真樹 <teuder at gmail.com> wrote:
> I find a bug in String::replace_last().
>
> I can reproduce the bug with the following code.
> (I also showed output of replace_first and replace_all for comparison.)
>
>
> =============
> // [[Rcpp::export]]
> void rcpp_string(){
>
> String s("abcdabcd");
> Rcout << "replace_first()\n";
> Rcout << s.replace_first("ab", "AB").get_cstring() << "\n";
> Rcout << "\n";
>
> s="abcdabcd";
> Rcout << "replace_last()\n";
> Rcout << s.replace_last("ab", "AB").get_cstring() << "\n";
> Rcout << "\n";
>
> s="abcdabcd";
> Rcout << "replace_all()\n";
> Rcout << s.replace_all("ab", "AB").get_cstring() << "\n";
> Rcout << "\n";
> }
> =============
>
> output
> =============
> replace_first()
> ABcdabcd
>
> replace_last()
> abcdaABd
>
> replace_all()
> ABcdABcd
> =============
>
>
> I also tried to fix the bug with following code. And the bug seems to be fixed.
>
> =============
> inline String& replace_last(const char* s, const char* news) {
> RCPP_STRING_DEBUG_2("String::replace_last(const char* = '%s' , const char* = '%s')", s, news);
> if (is_na()) return *this;
> setBuffer();
> //size_t index = buffer.find_last_of(s);
> size_t index = buffer.find_last_of(s) - (strlen(s)-1);
> Rcout << "A" << index << "\n";
> if (index != std::string::npos) buffer.replace(index, strlen(s), news);
> valid = false;
> return *this;
> }
> =============
>
> output
> =============
> replace_first()
> ABcdabcd
>
> replace_last()
> abcdABcd
>
> replace_all()
> ABcdABcd
> =============
>
>
> Mac OS 10.10.5
> R version 3.2.3
> Rcpp 0.12.4
>
>
> _______________________________________________
> Rcpp-devel mailing list
> Rcpp-devel at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
More information about the Rcpp-devel
mailing list