using System.Collections.Generic;
public static void Main()
var good = @"873x127752651,62.557895,-150.229389,""20,320 Alaskan Grill"",90000.90232.90287.91244,0,R,,,"""",,69.33,""(907) 733-2900"",""20 320 alaskan grill"",90000.90232.90287,101,,en-US,6;42;207,,20 320 Alaskan Grill;20 320 alaskan grill;,1414,false";
var bad = @"873x17957554381503831434,21.3648505359404,-157.949992163894,""USS Arizona Memorial (Temporarily Closed)"",90000.90001.90012;10000.10001.1785;10000.10001;90000.90001;90000.90001.90012.90016;90000.90298,,O,,,""ru:Мемориал линкора ""Аризона""/Национальный монумент воинской доблести в Тихом океане во время Второй мировой войны;ja:アリゾナ・メモリアル / 第二次世界大戦武勲記念史跡;es:USS Arizona Memorial;ar:سفينة يو إس إس أريزونا التذكارية;de:USS Arizona Memorial/World War II Valor in the Pacific National Monument;fr:USS Arizona Memorial/WW II Valor in the Pacific National Monument;it:USS Arizona Memorial;ko:USS 애리조나 기념관 / WWII 태평양 국립 기념비;nl:Het Gedenkteken van Arizona;nb:Minnesmerke etter andre verdenskrig i Arizona, USA;pl:Pomnik USS Arizona/Pomnik narodowy WW II Valor in the Pacific;pt:USS Arizona Memorial/Valor da 2ª Guerra Mundial no Monumento Nacional do Pacífico;sv:USS Arizonas minnesmonument i Pearl Harbor;tr:USS Arizona Memorial/WW II Valor in the Pacific National Monument;zh:美國海軍亞利桑那號戰艦紀念館;zh:USS 亚利桑那号纪念馆/二战太平洋国家纪念碑;"",,100.00,""(808) 422-3399"",""uss az memorial temporarily closed"",90000.90001.90012.90016,113,,en-US,,,USS Arizona Memorial Temporarily Closed;uss az memorial temporarily closed;Мемориал линкора Аризона Национальный монумент воинской доблести в Тихом океане во время Второй мировой войны;アリゾナ・メモリアル 第二次世界大戦武勲記念史跡;アリゾナ メモリアル 第 二 次 世界 大戦 武勲 記念 史跡;,1414,false";
var res = SplitLine(bad);
Console.WriteLine(res.Count);
for (int i = 0; i < res.Count; ++i) {
Console.WriteLine(res[i]);
public static List<String> SplitLine(string line)
var state = SplitState.LookingForField;
bool fieldStartedWithQuote = false;
var result = new List<string>();
char c = i < line.Length ? line[i] : (char)0;
case SplitState.LookingForField:
state = SplitState.ReadingField;
fieldStartedWithQuote = true;
state = SplitState.ReadingField;
fieldStartedWithQuote = false;
case SplitState.InteriorQuote:
state = SplitState.ReadingField;
if (fieldStartedWithQuote)
fieldStartedWithQuote = false;
state = SplitState.ReadingField;
case SplitState.ReadingField:
state = SplitState.InteriorQuote;
if (fieldStartedWithQuote)
state = SplitState.LookingForField;
int j = field.Length - 1;
while (j >= 0 && field[j] == ' ' || field[j] == '\t')
if (j < 0) { result.Add(null); }
else if (j < field.Length - 1)
result.Add(field.Substring(0, j + 1));
throw new InvalidOperationException();