возврат строки c ++ к консоли - PullRequest
0 голосов
/ 09 мая 2020

Я просто хочу знать, что не так с этим кодом C ++: мне нужно получить символы из консоли и подсчитать, сколько строк было написано. Затем мне нужно показать их в обратном порядке. То есть: если я напишу 3 строки: «привет», «им», «лукас» с '\ n' в конце каждой. Я должен перевернуть их, поэтому он пишет «lucas», «im», «hi», строка за строкой. Сначала подумал: я «сохраняю» строки в векторе «строк», а затем показываю их с помощью итератора, идущего от конца к началу. Я использую VSCode с g ++, и кажется, что проблема с последним вектором итератора l oop. Программа останавливается на этом и генерирует прерывание SIGINT. Почему это происходит? Как это исправить?

#include <iostream>
#include <vector>
using namespace std;
int  main()
{
    string strLines = "";
    int c;
    do {
        c = getc(stdin);
        strLines += c;
    } while (c != EOF);
    size_t oldIndex = 0;
    size_t newIndex;
    int totalStrings = 0;
    vector<string> strVector;
    while (1)
    {
        newIndex = strLines.find('\n', oldIndex);
        if (newIndex == string::npos)
            break;
        string strToPush = strLines.substr(oldIndex, newIndex+1);
        strVector.push_back(strToPush + '\0');
        oldIndex = newIndex+1;
        totalStrings++;
    } 
    //reverse string
    for (vector<string>::iterator it = strVector.end()-1 ; it != strVector.begin(); it--)
    {
        string strShow = *it;
        cout << *it;
    }
    c = getchar();
    return EXIT_SUCCESS;    
}

Ответы [ 2 ]

1 голос
/ 09 мая 2020

В том, что вы показали, много неправильного. Ненужные переменные, фактическая обратная итерация, плохие условия l oop, et c.

Вот код с вектором:

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

int main() {
  std::string line;
  std::vector<std::string> entries;

  do {
    std::cout << "Enter a thing: ";
    std::getline(std::cin, line);

    if (!line.empty()) {
      entries.push_back(line);
    } else {
      break;
    }
  } while (!line.empty());

  for (auto it = entries.rbegin(); it != entries.rend(); ++it) {
    std::cout << *it << ' ';
  }
  std::cout << '\n';
}

Если вы хотите go назад, вы используете обратный итератор. Это так просто. Но вектор - не идеальная структура данных для этого. Стеки подходят идеально.

#include <iostream>
#include <stack>
#include <string>

int main() {
  std::string line;
  std::stack<std::string> entries;

  do {
    std::cout << "Enter a thing: ";
    std::getline(std::cin, line);

    if (!line.empty()) {
      entries.push(line);
    } else {
      break;
    }
  } while (!line.empty());

  while (!entries.empty()) {
    std::cout << entries.top() << ' ';
    entries.pop();
  }
  std::cout << '\n';
}

Обе части кода дают вам то, что вы хотите, в гораздо более простом вопросе. Они завершают ввод пользователя l oop, когда вы просто нажимаете Enter, не набирая ничего (пустая строка). Используя преимущества Стандартной библиотеки (векторы, стеки, строки и т. Д. c.), Не торопитесь, чтобы ознакомиться с тем, что они могут делать. Скорее всего, обычные задачи позаботятся о вас.

1 голос
/ 09 мая 2020
  1. Нет необходимости в нулевом терминаторе std::string
  2. Вы никогда не добавляете последнюю строку в свой вектор, если вы встречаетесь с символом конца строки (\n), вы нарушаете и не добавляете последняя строка вектора. Вы можете решить эту проблему, добавив сразу после l oop strVector.push_back(strLines.substr(oldIndex))
  3. Как указано в комментариях @ sweeni sh, stack будет лучше
  4. Вы делаете много копий. Либо используйте std::move, либо копии на месте.
  5. В любом случае вы пропустите первый элемент, используйте rbegin() и rend()
  6. (Найдено при запуске), вы должны использовать substr(oldIndex, newIndex-oldIndex)
#include <iostream>
#include <vector>
using namespace std;
int  main()
{
    string strLines = "this\nis\nan\nexample\nfor\nsplitting";
    size_t oldIndex = 0;
    size_t newIndex;
    vector<string> strVector;
    while (1)
    {
        newIndex = strLines.find('\n', oldIndex);
        if (newIndex == string::npos) {
            break;
        }
        strVector.push_back(strLines.substr(oldIndex, newIndex-oldIndex));
        oldIndex = newIndex+1;
    } 
    strVector.push_back(strLines.substr(oldIndex));
    //reverse string
    for (auto it = strVector.rbegin() ; it != strVector.rend(); ++it)
    {
        cout << *it << "\n";
    }
    return EXIT_SUCCESS;    
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...