Как вернуть значение цикла foreach в c ++? - PullRequest
1 голос
/ 23 мая 2019

Мне нужно взять несколько строк строки, а затем добавить пробелы.

Я использую boost :: split, чтобы разделить строку и присвоить значение вектору.А затем внутри цикла for-each я добавляю пробелы к значению вектора.

static string test(){

    std::string text = "This is a sentence.\nAnd another sentence";
    string nl = "\n";
    string pad="     ";
    string txt;
    std::vector<std::string> results;

    boost::split(results, text, boost::is_any_of(nl));

    for(string line : results){
      txt = pad + line + nl;
      cout << txt;
    }
    return txt;
  }

Я должен получить возвращаемое значение, как показано ниже.Результат cout верен, но возвращаемое значение txt не может быть получено.

      This is a sentence.
      And another sentence

Ответы [ 4 ]

2 голосов
/ 23 мая 2019

1001 * имеющий *

 for(string line : results){
   txt = pad + line + nl;
   cout << txt;
 }
 return txt;

возврат txt - это last значение pad + line + nl из цикла или пустая строка, если results пусто

Высказывание

Результат cout верен, но возвращаемое значение txt не может быть получено.

вероятно означает, что вам нужно просто свернуть каждую строку и вернуть результат:

string r;

for(string line : results){
  txt = pad + line + nl;
  cout << txt;
  r += txt;
}
return r;

или что-то подобное может быть без pad

1 голос
/ 23 мая 2019

Я покажу часть функции, где вектор уже построен.Итак, функция, которую я покажу, упрощена, но демонстрирует, как вы можете построить и вернуть строку результата.

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

static std::string test( const std::vector<std::string> &results )
{    
    const std::string pad( "     " );

    std::string::size_type n = 0;
    for ( const std::string &s : results ) n += s.length();

    n += results.size() * ( pad.size() + sizeof( '\n' ) );

    std::string txt;
    txt.reserve( n );

    for ( const std::string &s : results ) txt += pad + s + '\n';

    return txt;
}

int main()
{
    std::vector<std::string> results = { "This is a sentence.", "This is a sentence." };

    std::cout << test( results );
}

Вывод программы:

 This is a sentence.
 This is a sentence.

Чтобы сделать код более эффективным, выдолжно зарезервировать достаточно места для строки txt.Цикл

    for ( const std::string &s : results ) n += s.length();

вычисляет общий размер всех строк, хранящихся в векторе.

Примечание: Вы можете использовать стандартный алгоритм std::accumulate, объявленный в заголовке<numeric> вместо цикла, как, например,

std::string::size_type n = std::accumulate( std::begin( results ), std::end( results ), 
                                            std::string::size_type( 0 ),
                                            []( const std::string::size_type acc, const std::string &s )
                                            {
                                                return acc + s.size();
                                            } );

Затем вы добавляете длину пробелов для каждой строки и длину символа '\n'.

Таким образом, все готовопостроить строку результата, которая возвращается из функции.

std::string txt;
txt.reserve( n );

for ( const std::string &s : results ) txt += pad + s + '\n';

return txt;
1 голос
/ 23 мая 2019

Ваш цикл:

for(string line : results){
  txt = pad + line + nl;
  cout << txt;
}
return txt;

сбрасывает txt на каждой итерации цикла (и вы печатаете текст этой итерации по одной за раз). После этого у вас останется только значение последней итерации после цикла.

Вместо этого добавьте к txt, чтобы сохранить все значения. Как следствие, вам также необходимо вывести cout из цикла:

for(string line : results){
  txt += pad + line + nl;
}
cout << txt;
return txt;
1 голос
/ 23 мая 2019

Другой способ:

static string test(){
    std::string text = "This is a sentence.\nAnd another sentence\n";
    std::string result = "   " + boost::algorithm::replace_all_copy(s, "\n", "\n    ");
    std::cout << result;
    return result;
}
...