некорректная обработка строк на С в Linux

Все о программировании под *nix
new_sergei
Заглянувший
Сообщения: 4
Зарегистрирован: 11 окт 2009, 20:44

некорректная обработка строк на С в Linux

Сообщение new_sergei »

Здравствуйте.
Мне необходимо посчитать количество символов в каждой строке входного файла и записать результат в выходной. Т.е., например, у нас есть текстовый файл вида

аааа
бб
ввв
ггг
ддддд

В выходном файле должна быть информация вида

Строка1 - 4 символа
Строка2 - 2 символа
Строка3 - 3 символа
Строка4 - 3 символа
Строка5 - 5 симолов

Всего - 5 строк 17 символов

В общем-то, саму программу я написал. Но вот как-то странно она работает. Когда запускаю её из под Windows, то всё Ок, а вот когда из под Linux, то для вышеуказанного примера выходной файл выглядит следующим образом

Строка1 - 4 символа
Строка2 - 2 символа
Строка3 - 3 символа
Строка4 - 3 символа
Строка5 - 5 симолов
Строка6 - 0 симолов

Всего - 5 строк 17 символов

Т.е., появляется лишняя запись о пустой 6-ой строке. Как это поправить?

Код ниже

Код: Выделить всё

#include <stdio.h>

#include <stdlib.h>




int main(int argc, char* argv[])

{

    FILE* in_file;

    FILE* out_file;

    int total_strings = 0;
    int total_symbols = 0;

    char* in_file_path; // path

    char* out_file_path;

    in_file_path = argv[1];
    out_file_path = argv[2];



    if (( in_file = fopen(in_file_path, "r")) == NULL)

    {

       printf("Failed to open an input file");

       exit(1);

    }

    if((out_file = fopen(out_file_path, "a")) == NULL)

    {

       printf("Failed to open an input file");

       exit(1);

    }



    else

    {

       char ch;

       int string_length = 0;

       int string_count = 0;



       do

       {

          ch = fgetc(in_file);

       

         if(ch != EOF)

         {



            if(ch == '\n' || ch == '\r') // if this is end of the line

            {

                  ++string_count;



                  fprintf(out_file, "%d",string_count);
                  fprintf(out_file, ". ");

                  fprintf(out_file, " %d ", string_length);

                  fprintf(out_file, "\n");


                  total_symbols += string_length;
                  ++total_strings;
                 

                  string_length = 0;

            }

            else

            {

                 string_length++;

            }



         }

         else // if file has ended - exit from program

         {

         ++string_count;



            fprintf(out_file, "%d",string_count);
            fprintf(out_file, ". ");

            fprintf(out_file, " %d ", string_length);

            fprintf(out_file, "\n");



            fprintf(out_file, "Total strings %d ",total_strings, ". ");

            fprintf(out_file, " Total symbols %d ", total_symbols);

            fprintf(out_file, "\n");
     

            string_length = 0;


            ch = fgetc(in_file);
            ch = fgetc(in_file);



             break;

         }

       

       } while(ch != EOF);

       return;

    }

}

Аватара пользователя
grub
Неотъемлемая часть форума
Сообщения: 849
Зарегистрирован: 13 сен 2006, 10:29
Откуда: Минск
Контактная информация:

Re: некорректная обработка строк на С в Linux

Сообщение grub »

Код: Выделить всё

if(ch == '\n' || ch == '\r') // if this is end of the line


Я вот не очень понял, почему она у тебя в виндах работала, если там каждая последовательность "\r\n" должна была при таком подходе трактоваться как два перевода строк и пустая строка между ними.

michael
Неотъемлемая часть форума
Сообщения: 434
Зарегистрирован: 12 апр 2004, 11:00
Откуда: г. Владивосток
Контактная информация:

Re: некорректная обработка строк на С в Linux

Сообщение michael »

Не знаю как в винде, а в линуксе всё выводится сообразно программе. Во-первых, у тебя две переменных: total_strings и string_count и счётчик строк выводит первую переменную, а номер строки - вторую. Кроме того, для последней строки string_count увеличивается (в результате номера строк пишутся правильно), а total_strings - нет (общее количество строк получается на единицу меньше). Ну а с нулём тоже всё просто. В конце последней строки в файле стоит '\n'. Программа на нём сбрасывает счётчик символов и увеличивает отсчёт строк. Ну а следующий прочитаный символ - это EOF. После EOFа у тебя выводится инфа о последней строки, которая получается пустой.

Как вся эта хрень умудрялась работать под виндой я не знаю. Вероятно, код, всё-таки, не одинаков был.

new_sergei
Заглянувший
Сообщения: 4
Зарегистрирован: 11 окт 2009, 20:44

Re: некорректная обработка строк на С в Linux

Сообщение new_sergei »

michael писал(а):Не знаю как в винде, а в линуксе всё выводится сообразно программе. Во-первых, у тебя две переменных: total_strings и string_count и счётчик строк выводит первую переменную, а номер строки - вторую. Кроме того, для последней строки string_count увеличивается (в результате номера строк пишутся правильно), а total_strings - нет (общее количество строк получается на единицу меньше). Ну а с нулём тоже всё просто. В конце последней строки в файле стоит '\n'. Программа на нём сбрасывает счётчик символов и увеличивает отсчёт строк. Ну а следующий прочитаный символ - это EOF. После EOFа у тебя выводится инфа о последней строки, которая получается пустой.

Как вся эта хрень умудрялась работать под виндой я не знаю. Вероятно, код, всё-таки, не одинаков был.


Спасибо за ответ. А как исправить код чтобы всё работало как надо?

Ответить