Ofstream записывает слишком много байтов

#c #fstream

#c #fstream

Вопрос:

У меня возникают некоторые проблемы, когда я хочу записать в файл. Основная цель этой программы — прочитать все данные из exe-файла и после записать их в другой exe-файл. Проблема в том, что когда я пишу новый файл, он записывает слишком много байтов. Например, я прочитал 45568 (n = 45568) байт, но в новом файле у меня 45800 байт, и я не понимаю, почему.

 #include <fstream>
#include <iostream>

int main(int argc, char** argv)
{
    using namespace std;

    ifstream file;
    file.open("a.exe", istream::in | ios::binary);

    std::streampos fsize = 0;
    fsize = file.tellg();

    file.seekg(0, std::ios::end);
    fsize = file.tellg() - fsize;
    file.close();

    int n = fsize;
    file.open("a.exe", istream::in | ios::binary);
    std::cout << n << " " << endl;

    int z=0;
    char *p = new  char[n 1];
    for (int i = 0;i < n;i  )
    {
        char ch;
        file.get(ch);
        p[i] = ch;
    }
    file.close();
    ofstream g;
    g.open("b.bin");
    std::cout << n;
    g.write(p, n);

    return 0;
}
  

Комментарии:

1. Как только у меня оба вызова open работают с одним и тем же файлом, я не могу воспроизвести.

2. это тот же файл. Я забыл изменить имена файлов, когда публиковал вопрос.

Ответ №1:

Измените эту строку:

 g.open("b.bin");
  

Чтобы быть таким:

 g.open("b.bin", istream::out | ios::binary);
  

В Windows (и устаревшей DOS, и многих других устаревших средах) файлы, открытые в текстовом режиме, получают специальную обработку для символа конца строки: n . Когда Windows записывает файл в текстовом режиме, все n символы записываются в file as, за r которым n следует. Аналогично, чтение файла в текстовом режиме преобразует rn последовательности в n . Открытие файлов в двоичном режиме отключает все это преобразование.

Кроме того, всю вашу программу можно упростить до:

 void main(int argc, char** argv)
{
    ifstream in;
    ofstream out;
    in.open("a.exe", istream::in | ios::binary);
    out.open("b.bin", istream::out | ios::binary);

    while (in.rdstate() == in.goodbit)
    {
        char c;
        if (in.get(c))
        {
            out.write(amp;c, 1);
        }
    }
}
  

Комментарии:

1. @AdrianPopescu — если ответ вас устраивает, не забудьте «Принять» ответ, поставив ему зеленую галочку.