читать неправильный файл в двумерный массив с помощью C ++ - PullRequest
1 голос
/ 25 сентября 2011

Я очень плохо знаком с C ++. Я считаю, что в stackoverflow уже есть решения, но я не могу их найти.

Мне нужно прочитать данные из текстового файла в двухмерный массив. Файл как

54 3 5 678

10 1 2 3 46 8 1 1 2 3 4

9 8 10

Каждая строка содержит до 120 целых чисел и не более 60 строк.

Ваш ответ высоко ценится. Спасибо!

Обновление: Это не домашняя работа . Спасибо всем!

Ответы [ 2 ]

4 голосов
/ 25 сентября 2011

Вот так ...

Определенно, вам нужен ответ 1 , хотя он очень правильный и верный природе C ++.

Вместо разбора на неровный массивчитает vector из vector с int с. (Или список сетов, стек дебетов, что угодно, что щекочет ваше воображение).

В отсутствие каких-либо спецификаций, я принимаю

  • любое числострок (до первой пустой),
  • любое число (> 0) чисел в любой строке
  • игнорирование пробелов в любом месте (кроме конца строки)
  • любое целое числоцифры (включая негативы ...)

Cheers

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/spirit/include/karma.hpp>

namespace spirit = boost::spirit;
namespace qi     = boost::spirit::qi;
namespace karma  = boost::spirit::karma;

int main()
{
    std::cin.unsetf(std::ios::skipws);
    spirit::istream_iterator b(std::cin), e;

    std::vector<std::vector<int> > vectors;

    if (qi::phrase_parse(b, e, +qi::int_ % qi::eol, qi::space - qi::eol, vectors))
        std::cout 
            << karma::format(karma::right_align(8)[karma::auto_] % ',' % '\n', vectors)
            << std::endl;

    return 0;
}

Для показанного ввода выводится:

  54,       3,       5,     678
  10,       1,       2,       3,      46,       8,       1,       1,       2,       3,       4
   9,       8,      10

Обновление Стандартная версия библиотеки

Смотрите в прямом эфире здесь: http://ideone.com/HtAAg

Для развлечения вот стандартверсия только для библиотеки того же самого.Просто чтобы показать, что не обязательно все так плохо, когда вы обходитесь без библиотек реактивного движения:)

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

static void display(const std::vector<int>& v)
{
    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, ",\t"));
    std::cout << std::endl;
}

int main()
{
    std::vector<std::vector<int> > vectors;

    std::string s;
    while (std::getline(std::cin, s))
    {
        std::istringstream iss(s);
        vectors.push_back(std::vector<int>());
        std::copy(std::istream_iterator<int>(iss), std::istream_iterator<int>(), std::back_inserter(vectors.back()));
    }

    std::for_each(vectors.begin(), vectors.end(), display);
    return 0;
}

1 Я предполагаю, что этоэто домашнее задание.Я также предполагаю, что ваш учитель хочет, чтобы вы выделили int[120][60] или int[60][120] (как вы узнали бы, сколько чисел было прочитано в строке? - вам понадобится дополнительное хранилище)

0 голосов
/ 25 сентября 2011

Мое решение, просто замените cin потоком файлов

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main(int argc, char* argv[]) {
    string line;
    int ints[60][120] = {0}, i = 0;
    stringstream ss;

    while (getline(cin, line)) {
        ss.str(line);

        for(int j = 0; j < 120 && ss; j++) {
            ss >> ints[i][j];
        }

        ss.clear();
        i++;
    }

    cin.ignore();
    return 0;
}
...