2013-03-31 4 views
5

Как проверить, является ли символ символом новой строки в любой кодировке в C?Проверка символа на новую строку

У меня есть задача написать собственный wc программа. И если я использую только, если (s[i] == '\n') имеет другой ответ, чем оригинал wc если я позвоню ему.
Вот код:

typedef struct 
{ 
    int newline; 
    int word; 
    int byte; 
} info; 

info count(int descr) 
{ 
    info kol; 
    kol.newline = 0; 
    kol.word = 0; 
    kol.byte = 0; 

    int len = 512; 
    char s[512]; 
    int n; 

    errno = 0; 
    int flag1 = 1; 
    int flag2 = 1; 
    while(n = read(descr, s, len)) 
    { 
     if(n == -1) 
      error("Error while reading.", errno); 

     errno = 0; 

     kol.byte+=n; 
     for(int i=0; i<n; i++) 
     { 
      if(flag1) 
      { 
       kol.newline++; 
       flag1 = 0; 
      } 

      if(isblank(s[i]) || s[i] == '\n') 
       flag2 = 1; 
      else 
      { 
       if(flag2) 
       { 
        kol.word++; 
        flag2 = 0; 
       } 
      } 
      if(s[i] == '\n') 
       flag1 = 1; 
     } 
    } 
    return kol; 
} 

Он отлично работает для всех текстовых файлов, но когда я называю его в файл я получил после компиляции сам он does't дать ответ туалет дает.

+1

Вы имеете в виду '' \ n''? – Useless

+0

'\ n' работает только в кодировке ASCII. Я имею в виду что-то вроде _isdigit() _ function – Taygrim

+0

Вы вызываете 'read (descr)', где 'descr' - предположительно файловый дескриптор. Как он был открыт? И * как * ваш результат отличается от вывода 'wc', и на каком входе? –

ответ

5

Способ проверки, является ли символ s[i] символом новой строки:

if (s[i] == '\n') 

Если вы чтение из файла, который был открыт в текстовом режиме (включая stdin), то все представление базовой системы использует, чтобы отметить конец строки будет переведено на один '\n' характера.

Вы говорите, что пытаетесь написать свою собственную программу wc, и сравнив ее с '\n', вы получаете разные результаты, чем wc. Вы не сказали нам достаточно, чтобы догадаться, почему это происходит. Покажите нам свой код и сообщите нам, что именно происходит.

У вас могут возникнуть проблемы, если вы читаете файл, который закодирован по-другому - скажем, пытаясь прочитать текстовый файл в формате Unix в системе Windows. Но тогда wc будет иметь такую ​​же проблему.

2

В ASCII и Unicode имеется несколько символов новой строки.

Наиболее известными являются \r и \n, от ASCII. Технически это возврат каретки и подача линии. Windows использует оба вместе: \r\n (технически каретки-возврат означает перейти в столбец 0, средства перевода строки идут в следующую строку, но ничего из того, что я знаю, повинуется тому, что на практике), unix использует только \n. Некоторые (не общие) ОС используют только \r.

Большинство приложений останавливаются на достигнутом и не страдают за это. Далее следует более теоретическое.

Юникод усложняет ситуацию. U + 000A и U + 000B идентичны \r и \n (то же двоичное представление в UTF-8). Тогда есть U + 0085 «следующая строка», U + 2028 «разделитель строк» ​​и U + 2029 «разделитель абзацев». Вы также можете проверить вертикальную вкладку (U + 000B), если хотите проверить все. Смотрите здесь: http://en.wikipedia.org/wiki/Newline#Unicode

+0

В старые времена некоторые машинописные машины нуждались в возврате каретки * и * linefeed .. –

+0

@xtofpernaud Хорошо, я знаю, что был трюк с очень старыми принтерами, чтобы заставить их накладывать символы поверх рисунков, но я действительно имел в виду все, что все еще обычно используется! – Dave

+0

\ r \ n все еще используется, например, все линейные протоколы (например, SMTP, IMAP, POP3) и другие (например, HTTP-заголовки) используют \ r \ n в качестве окончания строки. А также, если вы отправляете данные на терминал на низком уровне, я совершенно уверен, что \ r по-прежнему требуется для возврата в столбце 0. – Ale

1

Насколько я знаю, нет стандартной функции, как isXXXXX() них (наиболее близко один isspace(), что справедливо и для других условий (пространства, табуляции, ...). Простое сравнение с «\ n» должно решить вашу проблему, в зависимости от того, что вы считаете символом новой строки, вы также можете проверить «\ r» (возврат каретки). Стандарт UNIX в качестве разделителя строк - «\ n», Mac (до OS X) использовал «\ r» (теперь «\ n» является более распространенным, но иногда «\ r» используется некоторыми приложениями, например MS Office), DOS/Windows использует «\ r \ n», Последовательность

+0

Mac OS X использует '\ n', а не' \ r'. –

+0

Не во всех приложениях (см., Например, файлы CSV, экспортированные Excel в OS X) – Ale

+0

@ Возможно, это связано с тем, что Microsoft не заметила, что она изменилась в обновлении ... в общем, это '\ n', но это не так, это важно, потому что вы всегда должны проверять * что-либо *. Вы никогда не знаете, когда пользователь скопировал файл из другой ОС. – Dave

Смежные вопросы