C ++, как разобрать целые числа (и, возможно, удваивается) из символьного массива (или std :: string)? - PullRequest
2 голосов
/ 13 апреля 2011

Я работаю над простой программой и придерживаюсь этого несколько дней.

Как анализировать целые числа (и, возможно, удваивается) из массива символов? Если это будет проще, массив символов можно преобразовать в строку, Я имею в виду, это не обязательно должен иметь массив символов.

Я искал способ C ++

sscanf(mystring, "di %lf %lf %lf", &d1, &d2, &d3);

Проблема в том, что у меня будет несколько строк неизвестной длины (чисел). И у меня будут пробелы или запятые или что-то еще, разделяющее числа.

Токены - это путь? Из которых я ничего не знаю.

Ну, спасибо за любую помощь.

Ответы [ 3 ]

0 голосов
/ 13 апреля 2011

Я не слишком уверен, что вам действительно нужно. Похоже, вы не знать точный формат вашего файла. (Вы, конечно, не описал что-нибудь «точное».) Для преобразования целых или двойных из строки следует использовать istringstream. Если ты хочешь для поддержки различных разделителей, вы можете легко написать манипулятор, чтобы сделать это, что-то вроде:

class skipSeparators
{
    std::string mySeparators;
public:
    skipSeparators( std::string const& separators )
        : mySeparators( separators )
    {
    }
    friend std::ostream&
    operator>>(
        std::ostream& source,
        SkipSeparators const& manip )
    {
        source >> std::ws;
        int next = source.peek();
        if ( next != EOF
                && std::find( mySeparators.begin(),
                              mySeparators.end(),
                              static_cast<char>( next ) 
                            ) != mySeparators.end() ) {
            source.get();
        }
        return source;
    }
};

С этим вы можете написать что-то вроде:

while ( input >> skipSeparators( ",;" ) >> someDouble ) {
    //  process some double...
}

Если важно знать, где заканчивается строка, вы можете прочитать файл, используя getline(), и создайте istringstream для каждого линии, используя вышеупомянутое на нем.

0 голосов
/ 13 апреля 2011

Взгляните на Boost's lexical_cast, я думаю, это именно то, что вы хотите.Пример по ссылке:

int main(int argc, char * argv[])
{
    using boost::lexical_cast;
    using boost::bad_lexical_cast;

    std::vector<short> args;

    while(*++argv)
    {
        try
        {
            args.push_back(lexical_cast<short>(*argv));
        }
        catch(bad_lexical_cast &)
        {
            args.push_back(0);
        }
    }
    ...
}
0 голосов
/ 13 апреля 2011

Простые парсеры C ++ обычно выглядят примерно так ...

struct syntax_error : std::runtime_error {
    syntax_error( char const *str ) : std::runtime_error( str ) {}
};

std::istringstream iss( str ); // str is char*; use str.c_str() for std::string

std::string opcode;
long double args[ args_max ];

iss >> opcode; // read up to whitespace

for ( size_t arg_cnt = 0; arg_cnt < arg_counts[ opcode ]; ++ arg_cnt ) {
    if ( iss >> args[ arg_cnt ] ) { // read number, discard preceding whitespace
        throw syntax_error( "too few args" );
    }

    char delim;
    if ( ! ( iss >> delim ) || delim != ',' ) {
        throw syntax_error( "expected ',' delimiter" );
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...