![]() |
|
Модераторы: bsa |
![]()
|
|
| ddsoft |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 19.6.2012 Репутация: нет Всего: нет |
Подскажите, пожалуйста, как преобразовать конец строк файлов из Windows в Linux. Т.е. надо пару символов 0D 0A файла Windows преобразовать в символ 0A (как ф должно быть в файле Linux)? Нужно на классическом C. Я Делаю так. Открываю исходный файл читаю посимвольно из него и делаю проверку, если идут подряд два символа 0D0A, пишу в целевой файл только 0A. Но такое не работает. В итоге получается точная копия исходного файла. Использовал функции getc() и putc(). Посмотрел, что записывается в считываемый символ. Оказалось, что туда никогда не записывается символ 0D, только 0A. Поэтому и не работает проверка. Но в целевой файл-то пишется правильно и 0D и 0A. Как прочитать символ 0D?
Вот кусок, который читает их исходного файла:
Непонятно как в переменную ch пишется сразу два байта, т.к. при записы в файл оба байта там есть (0D0A). |
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 12 Всего: 72 |
Ты в какой операционке это делаешь?
В Линуксе твоя программа будет работать правильно. А вот в Windows по умолчанию при чтении 0D-0A ("\r\n") будет заменяться на 0A ('\n'), а при записи - 0A в автомате заменится 0D-0A. Чтобы этого не было, файл нужно откывать в двоичном режиме:
|
|||
|
||||
| feodorv |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Ну, Вы же код не привели, поэтому и комментировать нечего. Побайтовое чтение - не очень эффективно, но пусть будет.
Надо просто запоминать, что предыдущий символ был 0D, и если текущий - 0A, то 0D не записывать:
И не забывать проверять ошибки вызовов))) Это сообщение отредактировал(а) feodorv - 17.4.2013, 10:26 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||
|
|||||||
| ddsoft |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 19.6.2012 Репутация: нет Всего: нет |
Я делаю в Windows. Действительно, в линуксе работает как надо. Это особенность операционки при работе с текстовыми файлами? А как-нибудь можно, при работе с текстовыми файлами, указать в Windows, что не надо заменять при чтении 0D-0A на 0A? Да, при открытии в двоичном режиме всё работает. Спасибо! Это сообщение отредактировал(а) ddsoft - 18.4.2013, 06:59 |
|||
|
||||
| ddsoft |
|
||||||||||
|
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 19.6.2012 Репутация: нет Всего: нет |
Привожу код, преобразующий символы конца срок из Windows формата в Linux формат:
А как посоветуете сделать эффективнее?
Обнаружить символ 0D не получилось при открытии файла в текстовом режиме. А когда я поменял строки
на строки
всё заработало как надо. Мне такой код писал сразу два байта (\r\n) в файл, открытый в текстовом режиме.
А такой код у меня совсем не выполнялся. Это сообщение отредактировал(а) ddsoft - 17.4.2013, 23:10 |
||||||||||
|
|||||||||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
можно логику упростить. просто игнорировать 0xd, и все.
|
|||
|
||||
| feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Читайте, например, по 4 килобайта, выбрасывайте из буфера '\r' (длина буфера уменьшится), записывайте получившийся буфер...
Ну, с этим уже разобрались -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
| ddsoft |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 19.6.2012 Репутация: нет Всего: нет |
Что вы имеете ввиду? Можно поподробнее, пожалуйста? Добавлено @ 06:55 А что будет, если длина буфера окажется больше оставшегося куска файла? Автоматически буфер будет подгоняться под размер оствшегося куска файла или целевой файл окажется длиннее исходного на длину остатка буфера? Это сообщение отредактировал(а) ddsoft - 18.4.2013, 06:56 |
|||
|
||||
| feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Не понял, как это... Договорились же открывать файлы в бинарной моде, там чтение 1 в 1... Вот скелет алгоритма:
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 12 Всего: 72 |
Ну можно открыть файл в текстовом режиме, прочитать всё, и записать двоичном. Но так можно только в Windows, в Linux получите на выходе копию входного файла, поскольку там текстовый и двоичный режим не отличаются.
При чтении же в текстовом режиме режиме 0D не игнорируется 0D 0A и 0A 0D (стандарт MAC) заменяются на 0A. Одиночный 0D нужно либо оставлять так, либо заменять на 0A (есть ОС, в которых для разделения строк использется 0D) |
|||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
Как правильно заметил math64 код можно несколько упростить:
|
||||
|
|||||
| ddsoft |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 19.6.2012 Репутация: нет Всего: нет |
Я имел ввиду, что если буфер 4 килобайта, а файл 10 килобайт, то при двукратной записи буфера в файл, весь файл ещё не перепишется, а при трёхкратной целевой файл окажется уже 12 килобайт вместо 10 килобайт. По вашему коду теперь понял, что записываться будет только количество реально прочитанных байт.
Я об этом не подумал. Спасибо за наводку Спасибо! |
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
При преобравании виндозных файлов можно просто игнорировать. Если -же пишецца универсальный конвертер текстовых файлов любых операционок, то ни одна программа приведенная здесь работать правильно все равно не будет. |
|||
|
||||
| ddsoft |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 19.6.2012 Репутация: нет Всего: нет |
Допилил программу. Программа работает в windows и linux, преобразовывает концы строк win->unix и unix->win, имеет 3 входных параметра: 1) режим преобразования (win->unix или unix->win); 2) исходный файл; 3) целевой файл. Как на ваш взгляд можно сделать оптимальнее? Вот что у меня получилось:
|
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
||||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |