Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Файлы, обычный режим, и binary


Автор: cupper 19.1.2012, 10:20
Ненавижу файлы, сколько я с ними не работаю каждый раз новая и новая проблема возникает.

Почему если мы открываем файла как символьный при чтении get() из него символа '\n' у нас палзунок чтения скачет на 2 позиции. А если мы открывает файл как бинарный палзунок скачет на 1 позицию ?

Код

void test()
{
    {
        ofstream file ("testeee.file");
        if(!file.is_open())
            cerr << "Cannot open 'test1.file'\n";

        for(int i = 0; i < 3; i++)
            file << i << endl;
        file.close();
    }

    {
    fstream file("testeee.file", fstream::in | fstream::out);
    while(!file.eof())
    {
        int  after = file.tellg();
        int  sym = file.get();
        int  before = file.tellg();
        cout << "tell (before) = " << after <<" char = " << sym << " tell(after) = " << before << endl;
    }
    file.close();
    }

    {
    fstream file("testeee.file", fstream::in | fstream::out | fstream::binary);
    while(!file.eof())
    {
        int  after = file.tellg();
        int  sym = file.get();
        int  before = file.tellg();
        cout << "tell (before) = " << after <<" char = " << sym << " tell(after) = " << before << endl;
    }
    file.close();
    }
}


вывод
Код

tell (before) = 0 char = 48 tell(after) = 1
tell (before) = 1 char = 10 tell(after) = 3
tell (before) = 3 char = 49 tell(after) = 4
tell (before) = 4 char = 10 tell(after) = 6
tell (before) = 6 char = 50 tell(after) = 7
tell (before) = 7 char = 10 tell(after) = 9
tell (before) = 9 char = -1 tell(after) = -1

tell (before) = 0 char = 48 tell(after) = 1
tell (before) = 1 char = 13 tell(after) = 2
tell (before) = 2 char = 10 tell(after) = 3
tell (before) = 3 char = 49 tell(after) = 4
tell (before) = 4 char = 13 tell(after) = 5
tell (before) = 5 char = 10 tell(after) = 6
tell (before) = 6 char = 50 tell(after) = 7
tell (before) = 7 char = 13 tell(after) = 8
tell (before) = 8 char = 10 tell(after) = 9
tell (before) = 9 char = -1 tell(after) = -1


вот откуда там возникает ASSCII 13 корретки ?

Заранее спасибо.

Автор: feodorv 19.1.2012, 10:39
Цитата(cupper @  19.1.2012,  10:20 Найти цитируемый пост)
вот откуда там возникает ASSCII 13 корретки ?

Вот как раз '\r' и даёт сдвиг на 2 позиции вместо одной.

Дело в том, что Microsoft со времён первых DOS'ов считает, что строка в текстовом файле должна заканчиваться двумя символами - '\r' и '\n', а в UNIX'е изналально считалось, что строка должна заканчиваться лишь на символ '\n'. В конце концов, Microsoft пришла к компромиссу - двум режимам открытия файла. Если файл открывается в текстовом режиме, то '\r' в строке съедается (делается вид, что его там как бы и не было, аля Юникс), а если в бинарном - то '\r' остаётся.

Автор: spyswamp 19.1.2012, 11:04
Да, но парниша же говорит, что в текстовом режиме 2, а в бинарном 1. Каг таг?

Автор: bsa 19.1.2012, 11:09
Цитата(spyswamp @  19.1.2012,  12:04 Найти цитируемый пост)
Да, но парниша же говорит, что в текстовом режиме 2, а в бинарном 1. Каг таг?

очень просто. когда файл открыт в двоичном режиме, то символы читаются по одному без исключений. А если в текстовом, то в случае обнаружения символа '\r' (код 13) происходит еще одно считывание. В итоге смещение в файле сдвигается на 2 позиции.

Автор: spyswamp 19.1.2012, 11:31
Это был вопрос к последней строчке вообще-то:
>  Если файл открывается в текстовом режиме, то '\r' в строке съедается (делается вид, что его там как бы и не было, аля Юникс), а если в бинарном - то '\r' остаётся.

Либо у меня что-то с логикой. smile

Автор: cupper 19.1.2012, 11:43
Вашпе коллапс !!! smile

если я считанную в бинарном режиме строку в которой явно находится и \r и \n записываю обратно в файл (открытый в текстовом режиме), угадайте что происходит ? Правильно, я получаю по лишнему переводу строки после каждой строки smile

Автор: feodorv 19.1.2012, 11:56
Цитата(cupper @  19.1.2012,  11:43 Найти цитируемый пост)
Правильно, я получаю по лишнему переводу строки после каждой строки

Не совсем так. Там '\n' превращается в последовательность двух символов '\r' '\n'. Итого, при выводе в текстовый файл символов '\r' '\n' в файл запишутся три символа '\r' '\r' '\n'...

Цитата(spyswamp @  19.1.2012,  11:31 Найти цитируемый пост)
Это был вопрос к последней строчке вообще-то:

А что здесь не так?

Добавлено через 3 минуты и 34 секунды
В текстовом режиме для пользователя при чтении файла все сочетания '\r' '\n' превращаются в просто '\n'. Соответственно, при записи в файл '\n' превращается в '\r' 'n' прозрачным для пользователя образом.

Автор: bsa 19.1.2012, 12:00
Цитата(cupper @  19.1.2012,  12:43 Найти цитируемый пост)
Вашпе коллапс !!!

отсюда вывод: переходи на *nix - там нет таких проблем.

Автор: feodorv 19.1.2012, 12:07
Цитата(bsa @  19.1.2012,  12:00 Найти цитируемый пост)
отсюда вывод: переходи на *nix - там нет таких проблем. 

Можно и так))))
Я для себя давно решил все файлы открывать исключительно в бинарной моде, тогда никаких сюрпризов с указателями. Правда, при этом всегда нужно учитывать '\r'...

Автор: cupper 19.1.2012, 14:19
Всем спасибо, вопрос можно считать закрытым.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)