Есть ли итератор C ++, который может перебирать файл строка за строкой?

Отличное объяснение можно найти здесь: Сгенерировать скрипт в SQL Server Management Studio

Courtesy Ali Issa Вот что вам нужно сделать:

  1. Щелкните правой кнопкой мыши базу данных (а не таблицу) и выберите задачи -> сгенерировать скрипты
  2. Далее -> выбрать запрошенную таблицу / таблицы (из отдельных объектов базы данных)
  3. Далее -> нажмите advanced -> типы данных для скрипта = схема и данные

Если вы хотите создать скрипт, который просто генерирует таблицы (нет данные), вы можете пропустить расширенную часть инструкций!

46
задан thehouse 18 February 2010 в 21:24
поделиться

6 ответов

EDIT:Этот же трюк уже был описан кем-то другимв предыдущей теме.

Легко заставить std::istream_iterator делать то, что вы хотите:

namespace detail 
{
    class Line : std::string 
    { 
        friend std::istream & operator>>(std::istream & is, Line & line)
        {   
            return std::getline(is, line);
        }
    };
}

template<class OutIt>
void read_lines(std::istream& is, OutIt dest)
{
    typedef std::istream_iterator<detail::Line> InIt;
    std::copy(InIt(is), InIt(), dest);
}

int main()
{
    std::vector<std::string> v;
    read_lines(std::cin, std::back_inserter(v));

    return 0;
}
28
ответ дан 7 November 2019 в 11:06
поделиться

Вот довольно чистый подход, который использует повышение:: токенизатор . Это возвращает объект, обеспечивающий begin() и end() функции членства; для полного интерфейса см. документацию tokenizer класс .

#include <boost/tokenizer.hpp>
#include <iostream>
#include <iterator> 


using istream_tokenizer = boost::tokenizer<boost::char_separator<char>,
                                           std::istreambuf_iterator<char>>;

istream_tokenizer line_range(std::istream& is);
{
    using separator = boost::char_separator<char>;

    return istream_tokenizer{std::istreambuf_iterator<char>{is},
                             std::istreambuf_iterator<char>{},
                             separator{"\n", "", boost::keep_empty_tokens}};
}

Этот hardcodes char как тип символов потока, но это могло быть templatized.

функция может использоваться следующим образом:

#include <sstream>

std::istringstream is{"A\nBB\n\nCCC"};

auto lines = line_range(is);
std::vector<std::string> line_vec{lines.begin(), lines.end()};
assert(line_vec == (std::vector<std::string>{{"A", "BB", "", "CCC"}}));

Естественно, это может также использоваться с std::ifstream созданный путем открытия файла:

std::ifstream ifs{"filename.txt"};
auto lines = line_range(ifs);
0
ответ дан 7 November 2019 в 11:06
поделиться

Стандартная библиотека не предоставляет итераторов для этого (хотя вы можете реализовать что-то подобное самостоятельно), но вы можете просто использовать getline функцию (не метод istream) для чтения целой строки из входного потока в строку C++.

Пример:

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
    ifstream is("test.txt");
    string str;
    while(getline(is, str))
    {
        cout<<str<<endl;
    }
    return 0;
}
22
ответ дан 7 November 2019 в 11:06
поделиться

Ну, это IDisposable , так что я думаю, что это неплохая идея. Люди в MSFT сказали, что они сделали DataContexts как можно более легкими, чтобы вы могли создать их с безрассудным отказом, поэтому вы, вероятно, не набираете много, хотя.....

-121--1625098-

Вместо istreambuf_iterator можно использовать istream_iterator. Он не игнорирует управляющие символы, такие как istream_iterator.

code.cpp:

#include <iterator>
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream file("input.txt");

    istreambuf_iterator<char> i_file(file);

    istreambuf_iterator<char> eof;

    std::string buffer;
    while(i_file != eof)
    {
        buffer += *i_file;
        if(*i_file == '\n')
        {
            std::cout << buffer;
            buffer.clear();
        }
        ++i_file;
    }

    return 0;
}

input.txt:

ahhhh test *<-- There is a line feed here*
bhhhh second test *<-- There is a line feed here*

вывод:

ahhhh test
bhhhh second test
-121--1837984-

Вот решение. Исключение печатает входной файл с @ @ в конце каждой строки.

#include <iostream>
#include <iterator>
#include <fstream>
#include <string>

using namespace std;

class line : public string {};

std::istream &operator>>(std::istream &is, line &l)
{
    std::getline(is, l);
    return is;
}

int main()
{
    std::ifstream inputFile("input.txt");

    istream_iterator<line> begin(inputFile);
    istream_iterator<line> end;

    for(istream_iterator<line> it = begin; it != end; ++it)
    {
        cout << *it << "@@\n";
    }

    getchar();
}

Изменить: Мануэль был быстрее.

5
ответ дан 7 November 2019 в 11:06
поделиться

Вы можете написать свой собственный итератор. Это не так сложно. Итератор - это просто класс, на котором (проще говоря) определены операторы инкремента и *.

Посмотрите на http://www.drdobbs.com/cpp/184401417, чтобы начать писать свои собственные итераторы.

4
ответ дан 7 November 2019 в 11:06
поделиться

Вы можете использовать istreambuf_iterator вместо istream_iterator. Он не игнорирует управляющие символы, такие как istream_iterator.

code.cpp:

#include <iterator>
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream file("input.txt");

    istreambuf_iterator<char> i_file(file);

    istreambuf_iterator<char> eof;

    std::string buffer;
    while(i_file != eof)
    {
        buffer += *i_file;
        if(*i_file == '\n')
        {
            std::cout << buffer;
            buffer.clear();
        }
        ++i_file;
    }

    return 0;
}

input.txt:

ahhhh test *<-- There is a line feed here*
bhhhh second test *<-- There is a line feed here*

output:

ahhhh test
bhhhh second test
1
ответ дан 7 November 2019 в 11:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: