Парсинг разграниченного запятой станд.:: строка [дубликат]

У Armin Ronacher есть корректная идея. Проблемой являются случайные строки, может столкнуться. Я использовал бы:

<img src="picture.jpg?1222259157.415" alt="">

, Где "1222259157.415" текущее время на сервере.
Генерируют время JavaScript с performance.now() или Python с time.time()

121
задан Piku 12 December 2009 в 22:21
поделиться

8 ответов

Введите одно число за раз и проверьте, является ли следующий символ , . Если да, выбросьте его.

#include <vector>
#include <string>
#include <sstream>
#include <iostream>

int main()
{
    std::string str = "1,2,3,4,5,6";
    std::vector<int> vect;

    std::stringstream ss(str);

    for (int i; ss >> i;) {
        vect.push_back(i);    
        if (ss.peek() == ',')
            ss.ignore();
    }

    for (std::size_t i = 0; i < vect.size(); i++)
        std::cout << vect[i] << std::endl;
}
142
ответ дан 24 November 2019 в 01:27
поделиться
void ExplodeString( const std::string& string, const char separator, std::list<int>& result ) {
    if( string.size() ) {
        std::string::const_iterator last = string.begin();
        for( std::string::const_iterator i=string.begin(); i!=string.end(); ++i ) {
            if( *i == separator ) {
                const std::string str(last,i);
                int id = atoi(str.c_str());
                result.push_back(id);
                last = i;
                ++ last;
            }
        }
        if( last != string.end() ) result.push_back( atoi(&*last) );
    }
}
-1
ответ дан 24 November 2019 в 01:27
поделиться
bool GetList (const std::string& src, std::vector<int>& res)
  {
    using boost::lexical_cast;
    using boost::bad_lexical_cast;
    bool success = true;
    typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
    boost::char_separator<char> sepa(",");
    tokenizer tokens(src, sepa);
    for (tokenizer::iterator tok_iter = tokens.begin(); 
         tok_iter != tokens.end(); ++tok_iter) {
      try {
        res.push_back(lexical_cast<int>(*tok_iter));
      }
      catch (bad_lexical_cast &) {
        success = false;
      }
    }
    return success;
  }
0
ответ дан 24 November 2019 в 01:27
поделиться
std::string input="1,1,1,1,2,1,1,1,0";
std::vector<long> output;
for(std::string::size_type p0=0,p1=input.find(',');
        p1!=std::string::npos || p0!=std::string::npos;
        (p0=(p1==std::string::npos)?p1:++p1),p1=input.find(',',p0) )
    output.push_back( strtol(input.c_str()+p0,NULL,0) );

It would be a good idea to check for conversion errors in strtol(), of course. Maybe the code may benefit from some other error checks as well.

3
ответ дан 24 November 2019 в 01:27
поделиться

Еще один, довольно другой подход: используйте специальный языковой стандарт, который обрабатывает запятые как пробелы:

#include <locale>
#include <vector>

struct csv_reader: std::ctype<char> {
    csv_reader(): std::ctype<char>(get_table()) {}
    static std::ctype_base::mask const* get_table() {
        static std::vector<std::ctype_base::mask> rc(table_size, std::ctype_base::mask());

        rc[','] = std::ctype_base::space;
        rc['\n'] = std::ctype_base::space;
        rc[' '] = std::ctype_base::space;
        return &rc[0];
    }
}; 

Чтобы использовать это, вы imbue () поток с языковым стандартом, который включает этот аспект. Как только вы это сделаете, вы сможете читать числа, как если бы запятых вообще не было. Например, мы будем читать из ввода числа, разделенные запятыми, и затем выводить их по одной в каждой строке в стандартном выводе:

#include <algorithm>
#include <iterator>
#include <iostream>

int main() {
    std::cin.imbue(std::locale(std::locale(), new csv_reader()));
    std::copy(std::istream_iterator<int>(std::cin), 
              std::istream_iterator<int>(),
              std::ostream_iterator<int>(std::cout, "\n"));
    return 0;
}
61
ответ дан 24 November 2019 в 01:27
поделиться

Альтернативное решение с использованием общих алгоритмов и Boost.Tokenizer :

struct ToInt
{
    int operator()(string const &str) { return atoi(str.c_str()); }
};

string values = "1,2,3,4,5,9,8,7,6";

vector<int> ints;
tokenizer<> tok(values);

transform(tok.begin(), tok.end(), back_inserter(ints), ToInt());
17
ответ дан 24 November 2019 в 01:27
поделиться
#include <sstream>
#include <vector>

const char *input = "1,1,1,1,2,1,1,1,0";

int main() {
    std::stringstream ss(input);
    std::vector<int> output;
    int i;
    while (ss >> i) {
        output.push_back(i);
        ss.ignore(1);
    }
}

Неверный ввод (например, последовательные разделители) испортит это, но вы сказали просто.

2
ответ дан 24 November 2019 в 01:27
поделиться

Библиотека C ++ String Toolkit Library (Strtk) предлагает следующее решение вашей проблемы:

#include <string>
#include <deque>
#include <vector>
#include "strtk.hpp"
int main()
{ 
   std::string int_string = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15";
   std::vector<int> int_list;
   strtk::parse(int_string,",",int_list);

   std::string double_string = "123.456|789.012|345.678|901.234|567.890";
   std::deque<double> double_list;
   strtk::parse(double_string,"|",double_list);

   return 0;
}

Дополнительные примеры можно найти Здесь

44
ответ дан 24 November 2019 в 01:27
поделиться
Другие вопросы по тегам:

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