разбить длинную строку на несколько с ++ - PullRequest
5 голосов
/ 25 мая 2011

У меня есть строка, полученная от третьей стороны. Эта строка на самом деле является текстом из текстового файла и может содержать UNIX LF или Windows CRLF для завершения строки. Как я могу разбить это на несколько строк, игнорируя пустые строки? Я планировал сделать следующее, но не уверен, что есть лучший способ. Все, что мне нужно сделать, это прочитать построчно. Вектор здесь просто удобство и я могу этого избежать. * К сожалению, у меня нет доступа к реальному файлу. Я получаю только строковый объект *

string textLine;
vector<string> tokens;

size_t pos = 0;
while( true ) {
    size_t nextPos = textLine.find( pos, '\n\r' );
    if( nextPos == textLine.npos )
        break;
    tokens.push_back( string( textLine.substr( pos, nextPos - pos ) ) );
    pos = nextPos + 1;
}

Ответы [ 6 ]

6 голосов
/ 25 мая 2011

Вы можете использовать std::getline, когда вы читаете из файла, вместо того, чтобы читать все это в строку.Это будет разбивать вещи построчно по умолчанию.Вы просто не можете push_back ни одну строку, которая появляется пустой.

string line;
vector<string> tokens;

while (getline(file, line))
{
    if (!line.empty()) tokens.push_back(line);
}

UPDATE:

Если у вас нет доступа к файлу, вы можете использовать тот же код, инициализируя stringstream со всем текстом.std::getline работает со всеми типами потоков, а не только с файлами.

3 голосов
/ 25 мая 2011

Я бы использовал getline для создания новых строк на основе \ n, а затем манипулировал окончаниями строк.

string textLine;
vector<string> tokens;

istringstream sTextLine;
string line;
while(getline(sTextLine, line)) {
  if(line.empty()) continue;
  if(line[line.size()-1] == '\r') line.resize(line.size()-1);
  if(line.empty()) continue;
  tokens.push_back(line);
}

РЕДАКТИРОВАТЬ: используйте istringstream вместо stringstream.

2 голосов
/ 25 мая 2011

Я бы использовал приведенный здесь подход (std :: getline для std :: istringstream) ...

Разделение std :: string на C ++ с использованием токенов, например, ";"

... кроме пропуска ';'параметр для std :: getline.

1 голос
/ 25 мая 2011

Многое зависит от того, что уже присутствует в вашем наборе инструментов. я много работаю с файлами, которые приходят из Windows и читаются под Unix, и наоборот наоборот, поэтому у меня есть большинство инструментов для преобразования CRLF в LF. Если у вас его нет, вам может потребоваться функция, аналогичная:

void addLine( std::vector<std::string>& dest, std::string line )
{
    if ( !line.empty() && *(line.end() - 1) == '\r' ) {
        line.erase( line.end() - 1 );
    }
    if ( !line.empty() ) {
        dest.push_back( line );
    }
}

, чтобы сделать ваши вставки. Что касается разбивки исходного текста на строки, Вы можете использовать std::istringstream и std::getline, как и другие предложил; это просто и понятно, даже если это излишне. (std::istringstream - довольно тяжелый механизм, так как он поддерживает все виды входных преобразований, которые вам не нужны.) может рассмотреть цикл в соответствии с:

std::string::const_iterator start = textLine.begin();
std::string::const_iterator end   = textLine.end();
std::string::const_iterator next  = std::find( start, end, '\n' );
while ( next != end ) {
    addLine( tokens, std::string( start, next ) );
    start = next + 1;
    next = std::find( start, end, '\n' );
}
addLine( tokens, std::string( start, end ) );

Или вы можете разбить вещи на отдельные операции:

textLine.erase(
    std::remove( textLine.begin(), textLine.end(), '\r'),
    textLine.end() );

чтобы избавиться от всех ЧР,

std::vector<std:;string> tokens( split( textLine, '\n' ) );

, разбить его на строки, где split - обобщенная функция вдоль линий вышеупомянутого цикла (полезный инструмент, чтобы добавить к инструментарий) и, наконец,

tokens.erase(
    std::remove_if( tokens.begin(), tokens.end(), 
                    boost::bind( &std::string::empty, _1 ) ),
    tokens.end() );

. (Вообще говоря: если это одна из ситуаций, используйте std::istringstream решение на основе. Если вы думаете, что, возможно, придется сделать что-то подобное время от времени в будущем, добавьте split использовать ваш набор и использовать его.)

0 голосов
/ 25 мая 2011

Я бы поместил строку в поток строк и затем использовал метод getline, как и в предыдущем ответе. Затем вы можете просто вести себя так, как будто читаете текст из файла, если он действительно исходит из другой строки.

0 голосов
/ 25 мая 2011

Вы можете использовать strtok .

Разделить строку на токены

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...