Я подумал, что поучительно предложить разумную отправную точку для обхода.
Комментарии inline.
#include <memory>
#include <vector>
#include <array>
#include <type_traits>
#include <algorithm>
#include <iterator>
template<class Array> struct maker;
// a maker which makes a std::vector
template<class T, class A>
struct maker<std::vector<T, A>>
{
using result_type = std::vector<T, A>;
template<class...Ts>
auto operator()(Ts&&...ts) const -> result_type
{
result_type result;
result.reserve(sizeof...(Ts));
using expand = int[];
void(expand {
0,
(result.push_back(std::forward<Ts>(ts)),0)...
});
return result;
}
};
// a maker which makes std::array
template<class T, std::size_t N>
struct maker<std::array<T, N>>
{
using result_type = std::array<T, N>;
template<class...Ts>
auto operator()(Ts&&...ts) const
{
return result_type { std::forward<Ts>(ts)... };
}
};
//
// delegation function which selects the correct maker
//
template<class Array, class...Ts>
auto make(Ts&&...ts)
{
auto m = maker<Array>();
return m(std::forward<Ts>(ts)...);
}
// vectors and arrays of non-copyable types
using vt = std::vector<std::unique_ptr<int>>;
using at = std::array<std::unique_ptr<int>,2>;
int main(){
// build an array, using make<> for consistency
auto a = make<at>(std::make_unique<int>(10), std::make_unique<int>(20));
// build a vector, using make<> because an initializer_list requires a copyable type
auto v = make<vt>(std::make_unique<int>(10), std::make_unique<int>(20));
}
Я наконец-то добрался до чистки парсера, который был у меня в папке с кодом, и разместил его на Github: http://github.com/davedelong/CHCSVParser
Это довольно тщательно. Он обрабатывает всевозможные схемы экранирования, новые строки в полях, комментариях и т. Д. Он также использует интеллектуальную загрузку файлов, что означает, что вы можете безопасно анализировать огромные файлы в условиях ограниченной памяти.
Быстрый способ сделать это:
NSString * dataStr = [NSString (скрытая) кодировка: NSUTF8StringEncoding error: nil];
NSArray * array = [dataStr componentsSeparatedByString: @ ","];
Я нашел ParseKit несколько недель назад
Но ИМХО для большинства случаев - [NSString componentsSeparatedByString:]
метод и NSScanner
более чем достаточно и довольно просты в использовании.
Это, кажется, самое полное, что я нашел на данный момент.
http://www.macresearch.org/cocoa-scientists-part-xxvi-parsing-csv-data
В качестве побочного замечания, можно подумать, что большинство основных языков (Delphi, C#, Objective-c, php и т.д.) имеют библиотеку с полной реализацией этого основного формата обмена данными.
Я знаю, что json - это круто, а XML - надежно, но ни то, ни другое не доступно в качестве опции сохранения в большинстве приложений, сохраняющих табличные данные. CSV все еще доступен.
Я написал чрезвычайно простой (хотя и не полнофункциональный) анализатор CSV для проекта, над которым работал: CSVFile.h
и CSVFile.m
. Не стесняйтесь брать его - код доступен под GPLv3 (к сожалению, это было требованием для проекта, над которым я работал), но я был бы счастлив предоставить вам его по лицензии MIT или другой лицензии.