Скопируйте часть файла в C ++

В настоящее время я занят проектом, в котором мне нужно скопировать часть из файла в другой файл, поэтому я сделал для этого код, используя fread и fwrite. Но я столкнулся с проблемой: для целей тестирования я сделал код, который должен копировать весь файл, но каким-то образом код создает копии, которые больше, чем исходный файл. См. Код, который я сделал ниже

             FILE *base_file;
             FILE *new_file;
             fpos_t curpos;
             int tmp;

             // Open the base file
             fopen_s(&base_file, "C:/base.dat", "rb");
             // Open the file which should contain the copy
             fopen_s(&new_file, "C:/new.dat", "w");

             // Get the filesize
             fseek(base_file, 0, SEEK_END);
             fgetpos(base_file, &curpos);
             fseek(base_file, 0, SEEK_SET);

             //Read and copy (it seems to go wrong here)
             for(int i = 0; i < curpos; i++){
                 fread (&tmp, 1, 1, base_file);
                 fwrite(&tmp, 1, 1, new_file);
             }

             fclose(base_file);
             fclose(new_file);

Размер базового файла составляет 525 КБ, а нового файла - 527 КБ. Насколько я мог видеть, части, в которых возникает эта проблема, находятся после частей, где есть 7 нулевых байтов, и копия каким-то образом добавила '0D' (в шестнадцатеричном формате) после этих частей. В ascii символ «0D» - это «возврат каретки». Мне было интересно, в чем может быть причина того, что мой код копии добавляет в файл символы возврата каретки? Насколько я знаю, этот сценарий должен работать, поскольку я просто читаю базовый файл и напрямую копирую его в новый файл, а базовый файл не содержит этих возвратов каретки.


person Joey    schedule 01.10.2011    source источник
comment
Добавлен тег Windows, потому что этот fopen_s кажется изобретением MS. Поправьте меня если я ошибаюсь. Возможно, вы захотите открыть второй файл в режиме wb, кстати.   -  person Fred Foo    schedule 01.10.2011
comment
@larsmans: Это безопасная функция CRT, но она не имеет отношения к вопросу.   -  person Cat Plus Plus    schedule 01.10.2011


Ответы (2)


Вы открываете целевой файл в текстовом режиме, а не в двоичном, поэтому перевод новой строки происходит за вашей спиной. Измените режим на "wb".

Прочие примечания:

  1. Используйте потоки, а не stdio.
  2. Не пишите побайтно. Используйте больший буфер, ваш метод будет длиться вечно для больших файлов.
person Cat Plus Plus    schedule 01.10.2011
comment
Третье примечание: не используйте fopen_s, если вы все равно не проверяете возвращаемое значение. fopen более портативен и в равной степени (небезопасен), когда не выполняется проверка ошибок. - person Fred Foo; 01.10.2011
comment
Ну да, это покрыто вообще не использовать stdio. :П - person Cat Plus Plus; 01.10.2011
comment
Иногда может быть полезно использовать stdio. Я не знаком с MSVC, но обнаружил, что некоторые iostreams реализации все еще медленнее, чем stdio. - person Fred Foo; 01.10.2011
comment
Спасибо за все ответы! Смена режима на WB сработала, но я постараюсь последовать вашему совету и перейти на потоки вместо stdio. Также спасибо за подсказку по fopen_s. Я также перешел на использование буферного режима, я использовал побайтовый режим, чтобы облегчить поиск проблемы. - person Joey; 01.10.2011
comment
@larsmans: Ты делаешь ввод-вывод. Различия в скорости реализации незначительны, особенно для неформатированных операций. - person Cat Plus Plus; 01.10.2011
comment
Хм, да, для двоичного ввода-вывода разница будет незначительной. +1 кстати. - person Fred Foo; 01.10.2011

Исправит ли "wb" вместо "w"?

person Alexey Frunze    schedule 01.10.2011