Строка, не заменяющая слово

Поскольку все вопросы CSV, похоже, перенаправляются сюда, я думал, что отправлю свой ответ здесь. Этот ответ напрямую не затрагивает вопрос афера. Я хотел иметь возможность читать в потоке, который, как известно, находится в формате CSV, а также типы каждого поля уже были известны. Конечно, приведенный ниже метод можно использовать для обработки каждого поля как строкового типа.

В качестве примера того, как я хотел использовать входной поток CSV, рассмотрим следующий ввод (взятый из страница wikipedia на CSV ):

const char input[] =
"Year,Make,Model,Description,Price\n"
"1997,Ford,E350,\"ac, abs, moon\",3000.00\n"
"1999,Chevy,\"Venture \"\"Extended Edition\"\"\",\"\",4900.00\n"
"1999,Chevy,\"Venture \"\"Extended Edition, Very Large\"\"\",\"\",5000.00\n"
"1996,Jeep,Grand Cherokee,\"MUST SELL!\n\
air, moon roof, loaded\",4799.00\n"
;

Затем я хотел иметь возможность читать данные следующим образом:

std::istringstream ss(input);
std::string title[5];
int year;
std::string make, model, desc;
float price;
csv_istream(ss)
    >> title[0] >> title[1] >> title[2] >> title[3] >> title[4];
while (csv_istream(ss)
       >> year >> make >> model >> desc >> price) {
    //...do something with the record...
}

Это было решение, с которым я закончил.

struct csv_istream {
    std::istream &is_;
    csv_istream (std::istream &is) : is_(is) {}
    void scan_ws () const {
        while (is_.good()) {
            int c = is_.peek();
            if (c != ' ' && c != '\t') break;
            is_.get();
        }
    }
    void scan (std::string *s = 0) const {
        std::string ws;
        int c = is_.get();
        if (is_.good()) {
            do {
                if (c == ',' || c == '\n') break;
                if (s) {
                    ws += c;
                    if (c != ' ' && c != '\t') {
                        *s += ws;
                        ws.clear();
                    }
                }
                c = is_.get();
            } while (is_.good());
            if (is_.eof()) is_.clear();
        }
    }
    template  struct set_value {
        void operator () (std::string in, T &v) const {
            std::istringstream(in) >> v;
        }
    };
    template  struct set_value {
        template  void convert (std::string in, T &v) const {
            if (SIGNED) v = ::strtoll(in.c_str(), 0, 0);
            else v = ::strtoull(in.c_str(), 0, 0);
        }
        void operator () (std::string in, T &v) const {
            convert::val>(in, v);
        }
    };
    template  const csv_istream & operator >> (T &v) const {
        std::string tmp;
        scan(&tmp);
        set_value::val>()(tmp, v);
        return *this;
    }
    const csv_istream & operator >> (std::string &v) const {
        v.clear();
        scan_ws();
        if (is_.peek() != '"') scan(&v);
        else {
            std::string tmp;
            is_.get();
            std::getline(is_, tmp, '"');
            while (is_.peek() == '"') {
                v += tmp;
                v += is_.get();
                std::getline(is_, tmp, '"');
            }
            v += tmp;
            scan();
        }
        return *this;
    }
    template 
    const csv_istream & operator >> (T &(*manip)(T &)) const {
        is_ >> manip;
        return *this;
    }
    operator bool () const { return !is_.fail(); }
};

С помощью следующих помощников, которые могут быть упрощены с помощью новых шаблонов интегральных признаков в C ++ 11:

template  struct is_signed_int { enum { val = false }; };
template <> struct is_signed_int { enum { val = true}; };
template <> struct is_signed_int { enum { val = true}; };
template <> struct is_signed_int { enum { val = true}; };
template <> struct is_signed_int { enum { val = true}; };

template  struct is_unsigned_int { enum { val = false }; };
template <> struct is_unsigned_int { enum { val = true}; };
template <> struct is_unsigned_int { enum { val = true}; };
template <> struct is_unsigned_int { enum { val = true}; };
template <> struct is_unsigned_int { enum { val = true}; };

template  struct is_int {
    enum { val = (is_signed_int::val || is_unsigned_int::val) };
};

-1
задан Ryan 20 February 2019 в 02:39
поделиться

3 ответа

Вам необходимо переназначить значение переменной после replace, поскольку она не меняет исходную строку.

wiseProverb = wiseProverb.replace("shout", "speak");
0
ответ дан zmag 20 February 2019 в 02:39
поделиться

Вы не присвоили значение обратно wiseProverb. Вызвав .replace, вы создали новую строку с заменой.

wiseProverb = wiseProverb.replace("shout", "speak");

0
ответ дан mowwwalker 20 February 2019 в 02:39
поделиться

Метод replace() ищет в строке указанное значение или регулярное выражение и возвращает новую строку, в которой указанные значения заменяются.

Вы должны переназначить это значение чему-либо или просто распечатать преобразование.

var newWiseProverb = wiseProverb.replace("shout", "speak");
// this will only replace the first occurrence of that value.

// If you need to replace all occurrences you need to use a regex
var newWiseProverb = wiseProverb.replace(/shout/g, "speak");

// Or you can just  use that value in the placeholber
document.getElementById("anyplace").innerHTML = str.replace(/shout/g, "speak");

См. https://stackoverflow.com/a/54715766/2523147 для получения дополнительных комбинаций.

Если вы хотите копать дальше, обратитесь к https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace

[ 118] Метод replace () возвращает новую строку с некоторыми или всеми совпадениями шаблона, замененными заменой. Шаблон может быть строкой или RegExp, а замена может быть строкой или функцией, вызываемой для каждого совпадения. Если pattern является строкой, будет заменено только первое вхождение.

0
ответ дан prime 20 February 2019 в 02:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: