std :: replace дает ошибку

Я пытаюсь преобразовать путь к файлу, в котором есть только одна косая черта, в двойную косую черту, как показано в приведенном ниже коде. но это дает мне ошибку, показанную в конце

    #include<algorithm>

    std::string file_path;
    using std::replace;
     while(fgets(fname_buffer,1024,flist))
   {
    token = strtok( fname_buffer," ,\t");
    file_size=atol(token);

    token = strtok(NULL, " ,\t"); 
   strncpy((char*)file_fp,token,32);
   file_fp[32]='\0';

    token = strtok(NULL, "\n");
    file_path=token;
    replace(file_path.begin(),file_path.end(),'\\',"\\\\");
    //file_path.replace(file_path.begin(),file_path.end(),'\\','\\\\');

ошибка C2664: 'std :: basic_string ‹_Elem, _Traits, _Ax> & std :: basic_string‹ _Elem, _Traits, _Ax> :: replace (unsigned int, unsigned int, const _Elem *, unsigned int)': невозможно преобразовать параметр 1 из 'std :: _ String_iterator ‹_Elem, _Traits, _Alloc>' на 'unsigned int'


person John    schedule 01.03.2012    source источник
comment
Используйте this. Это намного лучше, чем алгоритмы поиска-замены-повтора.   -  person Benjamin Lindley    schedule 01.03.2012


Ответы (3)


replace не может заменить один символ '\\' двумя символами "\\\\". Сигнатура метода шаблона требует const T& для последних двух параметров, но вы передаете строку вместо символа.

Вот как вы можете сделать то, что вам нужно:

int p = 0;
while ((p = file_path.find('\\', p)) != string::npos) {
    file_path.insert(p, "\\");
    p += 2;
}
person Sergey Kalinichenko    schedule 01.03.2012
comment
Это должно быть file_path.insert(p, "\\\\"); - person Agnel Kurian; 04.03.2012
comment
@AgnelKurian нет, не совсем: другая косая черта уже есть. - person Sergey Kalinichenko; 04.03.2012

Вы пытаетесь заменить тип символа строкой - для замены требуется, чтобы типы были одинаковыми:
const T &, который в обоих случаях должен быть char.

template < class ForwardIterator, class T >
  void replace ( ForwardIterator first, ForwardIterator last,
                 const T& old_value, const T& new_value );

Вот фрагмент кода, который может оказаться полезным:
(Он работает путем повторных вызовов std::string::replace() до конца строки)

std::string& sReplaceAll(std::string& sS, 
                         const std::string& sWhat, 
                         const std::string& sReplacement)
{
    size_t pos = 0, fpos;
    while ((fpos = sS.find(sWhat, pos)) != std::string::npos)
    {
        sS.replace(fpos, sWhat.size(), sReplacement);
        pos = fpos + sReplacement.size();
    }
    return sS;
}

В вашем случае вы бы использовали это так:

sReplaceAll(file_path, "\\", "\\\\");

person slashmais    schedule 01.03.2012
comment
Было бы неплохо предложить решение, здесь замена '\\' на "\\" заставит код работать. - person Matthieu M.; 01.03.2012
comment
@MatthieuM: это не сработало (это дало ошибку времени выполнения). Обратный путь работал, но он заменил все символы в пути на '\' - person John; 01.03.2012
comment
Я не думаю, что это сработает, поскольку char* нельзя назначить char, который является элементом std::string. - person hmjd; 01.03.2012
comment
@MatthieuM. Я не думаю, что замена '\\' на "\\" жизнеспособна, потому что std::string является контейнером символов, а не строк. Другими словами, T в шаблоне должен быть привязан к одному символу, а не к строке (ваше предложение будет работать с вектором строк, хотя оно будет делать другое). - person Sergey Kalinichenko; 01.03.2012
comment
@hmjd: точно, извините, я думал, что это замена регулярного выражения, а не алгоритм. Джон: верно, здесь вы обречены на провал с этим алгоритмом. - person Matthieu M.; 01.03.2012
comment
Я пробовал это. Я получил 'void std :: replace (_FwdIt, _FwdIt, const _Ty &, const _Ty &)': параметр шаблона '_Ty' неоднозначен - person John; 01.03.2012
comment
Ясно, что это не работает. Вы должны протестировать свой код, прежде чем публиковать его в качестве ответа. - person Benjamin Lindley; 01.03.2012

copy, replace, transform и некоторые другие алгоритмы не могут создать больше элементов, чем существует в их входном диапазоне. (в голове я не могу придумать никаких стандартных алгоритмов, которые позволяют это)

Для этого можно использовать regex_replace:

file_path = std::regex_replace(file_path,std::regex("\\"),"\\\\");
person bames53    schedule 01.03.2012
comment
компилятор говорит, что regex_replace не является членом std - person John; 01.03.2012
comment
#include <regex>. Если вы используете версию VS до VS2010, вам придется использовать версию std::tr1. - person bames53; 01.03.2012