metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2012-04-22 06:05 pm

C, parse comma-separated line

Кошерен ли такой код для разбиения строки, разделенной запятыми на отдельные строки: http://ideone.com/rhNXq ?

PS: strtok не признаю по идеологическим причинам - она меняет анализируемую строку, что меня крайне пугает, хотя в моем конкретном случае это не мешает.

PPS: безотносительно к strtok, в функции было минимум две ошибки - отсутствие проверки на выход за пределы буфера и попадание eol в последнюю строку (девайсина, с которой приходит строка, терминирует ее \r)

[identity profile] blacklion.livejournal.com 2012-04-22 04:44 pm (UTC)(link)
А этот код разруливает? Вообще, приличного кода с полной поддержкой shell words я как-то не видел ни разу.

[identity profile] metaclass.livejournal.com 2012-04-22 04:51 pm (UTC)(link)
Написать нормальный парсер CSV с экранированием это та еще задача. Можно давать на собеседовании и издеваться.

[identity profile] http://users.livejournal.com/_slw/ 2012-04-22 07:42 pm (UTC)(link)
use Text::CSV;
$csv = Text::CSV->new({binary => 1, sep_char => ';'});
$status = $csv->parse($_);
foreach $f ($csv->fields()){
....
}

[identity profile] lionet.livejournal.com 2012-04-22 05:28 pm (UTC)(link)
На Эрланге примерно так:

extract_value([]) -> novalue;
extract_value([$\r,$\n|Rest]) -> {Rest};
extract_value([$\n|Rest]) -> {Rest};
extract_value([$"|Rest]) -> extract_quoted(Rest, []);
extract_value(Rest) -> extract_nonquoted(Rest, []).

extract_nonquoted([$\n|_]=Rest, V) -> {V, Rest};
extract_nonquoted([$\r,$\n|_]=Rest, V) -> {V, Rest};
extract_nonquoted([$,|Rest], V) -> {V, Rest};
extract_nonquoted([C|Rest], V) -> extract_nonquoted(Rest, [C|V]);
extract_nonquoted([], V) -> {V, []}.

extract_quoted([$",$,|Rest], V) -> {V, Rest};
extract_quoted([$",$\r,$\n|Rest], V) -> {V, [$\n|Rest]};
extract_quoted([$",$\n|Rest], V) -> {V, [$\n|Rest]};
extract_quoted([$",$"|Rest], V) -> extract_quoted(Rest, [$"|V]);
extract_quoted([$"], V) -> {V, []};
extract_quoted([$\r,$\n|Rest], V) -> extract_quoted(Rest, [$\n|V]);
extract_quoted([C|Rest], V) -> extract_quoted(Rest, [C|V]);
extract_quoted([], V) -> {V, []}.

[identity profile] blacklion.livejournal.com 2012-04-22 05:24 pm (UTC)(link)
Смотреть надо — понимает ли он заэскейпленные кавычки в кавычках и прочее.

[identity profile] lionet.livejournal.com 2012-04-22 05:27 pm (UTC)(link)
Понимает. И прочее.