Отличное объяснение можно найти здесь: Сгенерировать скрипт в SQL Server Management Studio
Courtesy Ali Issa Вот что вам нужно сделать:
Если вы хотите создать скрипт, который просто генерирует таблицы (нет данные), вы можете пропустить расширенную часть инструкций!
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;
}
Вот довольно чистый подход, который использует повышение:: токенизатор . Это возвращает объект, обеспечивающий 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);
Стандартная библиотека не предоставляет итераторов для этого (хотя вы можете реализовать что-то подобное самостоятельно), но вы можете просто использовать 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;
}
Ну, это IDisposable
, так что я думаю, что это неплохая идея. Люди в MSFT сказали, что они сделали DataContexts как можно более легкими, чтобы вы могли создать их с безрассудным отказом, поэтому вы, вероятно, не набираете много, хотя.....
Вместо 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();
}
Изменить: Мануэль был быстрее.
Вы можете написать свой собственный итератор. Это не так сложно. Итератор - это просто класс, на котором (проще говоря) определены операторы инкремента и *.
Посмотрите на http://www.drdobbs.com/cpp/184401417, чтобы начать писать свои собственные итераторы.
Вы можете использовать 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