Изменить байт в бинарном файле

  • Автор темы byte255
  • Дата начала
B

byte255

Гость
#1
Здравствуйте. Подскажите пожалуйста, мне нужно изменить байт в бинарном файле, для чего использую такой код
C++:
void BinFile::writeByte(long pos, short byte) 
{
ofstream bin(this->filename, ios_base::binary);
bin.seekp(pos,ios_base::beg);
bin.put(byte);
bin.close();
}
Байт исправно записывается, но прочие байты файла устанавливаются в 0.
Компилятор g++, система linux ubuntu 9.10.
 
I

ierofant

Гость
#2
put для файловых потоков не очень годится.

Вот так в моём файле я сделал замену для третьего символа.
C++:
		std::ifstream in ("file", std::ios::binary);
in.seekg (0, std::ios::end);
int size = in.tellg ();
char mas [size];

in.seekg (0, std::ios::beg);
in.read (mas, sizeof mas);
in.close ();

mas [3] = 0x33;

std::ofstream out ("file", std::ios::binary | std::ios::trunc);
out.write (mas, sizeof mas);
out.close ();
Добавлено: Чуть не обманул вас, можно вот так:
C++:
	char sym = 0x33;
std::ofstream out ("file", std::ios::binary);
out.seekp (3, std::ios::beg);
out.write (&sym, sizeof sym);
out.close ();
 
B

byte255

Гость
#3
Спасибо!!!
К сожалению, в линуксе не отработало... те же нули вместо всех остальных байтов. Приду домой, в виндовс попробую.
В какой среде ваш код отработал?
 

Гость
#4
Попробуйте так:
C++:
void BinFile::writeByte (long pos, short byte)
{
ofstream bin (this->filename, ios_base::binary | ios_base::ate);
bin.seekp (pos, ios_base::beg);
bin.put (byte);
bin.close ();
}
То есть всё то же самое, только в открытии файла надо указать параметр ate.
Если не поможет, то больше у меня нет идей.
 
B

byte255

Гость
#5
Попробуйте так:
C++:
void BinFile::writeByte (long pos, short byte)
{
ofstream bin (this->filename, ios_base::binary | ios_base::ate);
bin.seekp (pos, ios_base::beg);
bin.put (byte);
bin.close ();
}
То есть всё то же самое, только в открытии файла надо указать параметр ate.
Если не поможет, то больше у меня нет идей.
Не помогло (
Тот же вопрос, если не трудно, чем компилировали?
 
I

ierofant

Гость
#6
Мой код работает на ubuntu-10.04. Компилятор gcc. Но это по идее не должно зависеть от компилятора и операционки. Это же стандартные функции С++.

Добавлено: Попробуйте так.

C++:
void BinFile::writeByte(long pos, char byte) 
{
std::ofstream bin(this->filename, std::ios::binary);
bin.seekp (pos, std::ios::beg);
bin.write (&byte, sizeof byte);
bin.close();
}
 
I

ierofant

Гость
#7
А ещё мне интересно, зачем вы пишите this->filename, а не просто filename?
 
B

byte255

Гость
#8
Мой код работает на ubuntu-10.04. Компилятор gcc. Но это по идее не должно зависеть от компилятора и операционки. Это же стандартные функции С++.

Добавлено: Попробуйте так.

C++:
void BinFile::writeByte(long pos, char byte) 
{
std::ofstream bin(this->filename, std::ios::binary);
bin.seekp (pos, std::ios::beg);
bin.write (&byte, sizeof byte);
bin.close();
}
У меня ubuntu 9.10. На всякий случай просто скопировал ваш код, но результат тот же. Правда я g++ использую, сейчас попробую gcc (
до сих пор думал, что им программы на C (но не С++) компилируются).
 
I

ierofant

Гость
#9
Дело в том, что g++ это расширение gcc, для c++. Я компилю тоже через g++. Просто сам компилятор правильнее называть gcc.
 
B

byte255

Гость
#10
Дело в том, что g++ это расширение gcc, для c++. Я компилю тоже через g++. Просто сам компилятор правильнее называть gcc.
Учту, спасибо за помощь. Однако,в чем же может дело быть...
C++:
int main()
{
BinFile f("./main.o");
f.writeByte(10, 'n'); //в определении writeByte() - абсолютная копия вашей функции
return 0;
}
Команда для компиляции:
Код:
#!/bin/bash
gcc -c binfile.cpp main.cpp 
g++ -Xlinker binfile.o main.o -o testwriter
или
Код:
g++ binfile.cpp main.cpp -o testwriter
В результате размер файла main.o становится 10 байт, в последнем 0x6E
 
I

ierofant

Гость
#11
Делай тогда, через чтение, а потом запись. Смотри самый-самый первый пример у меня.
 
I

ierofant

Гость
#12
Как-то так.

C++:
void write_byte (long _pos, char _sym)
{
std::ifstream in (filename, std::ios::binary);
in.seekg (0, std::ios::end);
int size = in.tellg ();

char mass [size];
in.seekg (0, std::ios::beg);
in.read (mass, sizeof mass);

mass [_pos] = _sym;

std::ofstream out (filename, std::ios::binary | std::ios::trunc);
out.write (mass, sizeof mass);
out.close ();
}
 
B

byte255

Гость
#13
Да, а если в файле более гигабайта? Копировать в память?
вот истина =)
C++:
 void BinFile::writeByte(long pos, char byte)
{
ofstream bin(this->filename, ios_base::in|ios_base::binary); 
bin.seekp(pos,ios_base::beg);
bin.put(byte);
bin.close();
}