Разбор строки в массив для C ++ - PullRequest
1 голос
/ 17 июня 2020

Как мне преобразовать строку в массив в C ++?

Например: "[1:2:3:4]cd/dvd PLDS DVD-RW DU8A6SH DU53 /dev/sr0"

Я хочу получить массив целых чисел внутри квадратной скобки []. Итак, массив содержит {1, 2, 3, 4}.

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

std::string test = "[1:2:3:4]cd/dvd  PLDS  DVD-RW DU8A6SH DU53  /dev/sr0";
int begin = test.find("[");
begin = begin + 1;
std::string sub = test.substr(begin,7);
std::replace(sub.begin(), sub.end(), ':', ' ');

std::vector<int> arr;
std::stringstream ss(sub);
int temp;
while (ss >> temp)
     arr.push_back(temp);

Примечание: что-то будет не быть раньше "[". "[" будет всегда. Число всегда будет 1 di git каждое. В квадратных скобках всегда будет четыре целых числа. "]" будет всегда. Текст всегда следует после "]".

Ответы [ 3 ]

0 голосов
/ 17 июня 2020

Учитывая добавленные вами ограничения, вы можете попробовать следующее:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>

int main() {
    std::string test = "[1:2:3:4]cd/dvd  PLDS  DVD-RW DU8A6SH DU53  /dev/sr0";

    std::vector<int> v(4);
    {
        char open_square_bracket, colon1, colon2, colon3, close_square_bracket;
        std::stringstream ss(test);
        ss >> open_square_bracket >> v[0] >> colon1 >> v[1] >> colon2 >> v[2] >> colon3 >> v[3] >> close_square_bracket;
    }

    copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, ", "));
    std::cout << "\n";

    return 0;
}

Конечно, важная часть - это та часть, которую я вставил в оператор блока, чтобы выделить его. Это позволяет вам также проверить, являются ли персонажи такими, какими они должны быть. В противном случае, если вы на 100% уверены, что формат будет правильным, его можно упростить до

    std::vector<int> v(4);
    char c;
    std::stringstream ss(test);
    ss >> c >> v[0] >> c >> v[1] >> c >> v[2] >> c >> v[3] >> c;

. Вы также можете обернуть это в for l oop, но если это всегда 4 элемента, зачем?

Конечно, в этом случае можно использовать std::array<>:

    std::array<int, 4> v;
    char c;
    std::stringstream ss(test);
    ss >> c >> v[0] >> c >> v[1] >> c >> v[2] >> c >> v[3] >> c;

Запустить на ideone .

0 голосов
/ 17 июня 2020

Поскольку вы жестко запрограммировали размер substr(), это означает, что числа имеют фиксированные позиции и ширину, и в этом случае вы можете просто использовать это вместо:

#include <string>
#include <array>

std::string test = "[1:2:3:4]cd/dvd  PLDS  DVD-RW DU8A6SH DU53  /dev/sr0";

std::array<int, 4> arr; // or: int arr[4]; pre-C++11
for(int i = 1, j = 0; i < 9; i += 2, ++j)
    arr[j] = test[i]-'0';

Live Demo

Однако, если это не так, не делайте предположений о том, где находится закрывающий ]. Используйте find(), чтобы найти его, например:

std::string test = "[1:2:3:4]cd/dvd  PLDS  DVD-RW DU8A6SH DU53  /dev/sr0";

std::string::size_type begin = test.find('[') + 1;
std::string::size_type end = test.find(']', begin);
std::string sub = test.substr(begin, end - begin);

std::vector<int> arr;
std::istringstream iss(sub);
int temp;

while (iss >> temp) {
    arr.push_back(temp);
    iss.ignore();
}

Live Demo

Если вы используете C ++ 17 или новее, вы можете использовать std::string_view и std::from_chars(), чтобы уменьшить накладные расходы на память, поэтому вам не нужно выделять отдельный std::string для sub или std::istringstream или даже использовать std::istringstream, например:

std::string test = "[1:2:3:4]cd/dvd  PLDS  DVD-RW DU8A6SH DU53  /dev/sr0";
std::string_view sv(test.data(), test.size());

std::string_view::size_type begin = sv.find('[') + 1;
std::string_view::size_type end = sv.find(']', begin);
std::string_view sub = sv.substr(begin, end - begin);

std::vector<int> arr;
const char *pBegin = sub.data(), *pEnd = pBegin + sub.size();
int temp;

while (pBegin < pEnd)
{
    auto [ptr, ec] = std::from_chars(pBegin, pEnd, temp);
    if (ec != std::errc()) break;
    arr.push_back(temp);
    pBegin = ptr + 1;
}

Живая демонстрация

0 голосов
/ 17 июня 2020
int main()
{
    std::string str = "[1:2:3:4]aaa";
    std::vector<int> str_chars = {};

    for (unsigned int i = 0; i < str.size(); ++i)
    {
        char curr = str.at(i);
        if (str.at(i) == '[')
        {
            str_chars.push_back((str.at(i + 1) - '0'));
        }
        else if ((str.at(i) == ':'))
        {
            str_chars.push_back(str.at(i + 1) - '0');
        }
    }

    for (int i = 0; i < str_chars.size(); ++i)
    {
        printf("%d ", str_chars.at(i));
    }

    getchar();
    return 0;
}
...