Como armazenar o valor inteiro “0” em um arquivo .bin? (C ++)
-
06-09-2019 - |
Pergunta
EDIT: Aparentemente, o problema está na função de leitura: Eu verifiquei os dados em um hex editer
02 00 00 00 01 00 00 00 00 00 00 00
Assim, o zero é sendo armazenado como zero, simplesmente não lido como zero.
Porque quando eu usar a minha função de arquivo store-in-bin normal:
int a = 0;
file.write(reinterpret_cast<char*>(&a), sizeof(a));
Ele armazena 0 como a versão char
, ou "\ 0", o que obviamente não é armazenada (porque é um valor nulo?) Então quando eu chamar minha função para ler o valor zero, ele lê o valor correto depois (ou para a direita antes de se seria o último no arquivo). Então, como posso armazenar de zero em um arquivo .bin corretamente?
EDIT: Aqui estão algumas das funções relacionadas com o processo de leitura / gravação:
//Init program: creates a sector.bin for another program to read from.
#include<fstream>
using namespace std;
int main()
{
fstream file;
file.open("sector.bin", ios::out | ios::binary);
if(!file.is_open())
{
file.open("sector.bin", ios::out | ios::binary);
file.close();
file.open("sector.bin", ios::out | ios::binary);
if(!file.is_open())
{
return -1;
}
}
file.seekp(file.beg);
int a = 2;
int b = 1;
int c = 0;
file.write(reinterpret_cast<char*>(&a), sizeof(a));
file.write(reinterpret_cast<char*>(&b), sizeof(b));
file.write(reinterpret_cast<char*>(&c), sizeof(c));
file.close();
return 0;
}
//Read function: part of another program that intializes variables based off
//of sector.bin
void sector::Init(std::fstream& file)
{
int top_i = FileRead(file,0);
std::cout<<top_i<<std::endl;
for(int i = 0; i < top_i; i++)
{
accessLV[i] = FileRead(file,i+1);
std::cout<<accessLV[i]<<std::endl;
}
std::cin.ignore();
viral_data.add(new X1(5,5,'X'));
viral_data.add(new X1(9,9,'X'));
player.set(0,0,'O');
return;
}
//the FileRead used in init
int FileRead(std::fstream& file, int pos)
{
int data;
file.seekg(file.beg + pos);
file.read(reinterpret_cast<char*>(&data), sizeof(data));
return data;
}
Além disso, a saída para o uso sector::Init
é o seguinte:
2
1
1
O ouput que eu estava tentando escrever para o lixo era
2
1
0
Assim, ou a 0 está a ser lido / escrito como um 1, ou a sua não sendo escrito e Init está lendo o último valor duas vezes.
Solução
Não está claro o que você quer dizer com "armazenar valor inteiro 0" em um arquivo. Arquivos contêm bytes, não inteiros. Você precisa armazenar sizeof (int) 0-bytes, ou apenas uma '\ 0' byte?
P.S. Eu também diria o problema pode estar no seu código de leitura. Você olha para o seu arquivo .bin em um editor hexadecimal?
P.P.S. Seu problema está em seekg utilização da função (). Em vez de passar o deslocamento em bytes, você passar pos. Deve ser pos * sizeof (int) em vez.
Outras dicas
int num = 0;
write( fd, &num, sizeof( int ));
Eu não tenho certeza do que você quer fazer, me parece que o código fornecido faz o que você está pedindo:
int main() {
std::ofstream file("/tmp/tst.out");
int a = 0;
file.write(reinterpret_cast<char*>(&a), sizeof(a));
return 0;
}
Isso resulta em um arquivo de quatro bytes tamanho que contém a representação binária de um número inteiro zero:
$ hexdump /tmp/tst.out
0000000 0000 0000
0000004
Se você deseja armazenar o número inteiro como é a representação ASCII você deve usar a saída de fluxo formatado com <<
:
std::ofstream file("/tmp/tst.out");
int a = 0;
file << a << std::endl;
Desta forma, você obtém:
$ cat /tmp/tst.out
0
Você precisa pensar qual o formato do arquivo binário deve conter - algo que você não tem que fazer da mesma forma com arquivos de texto, razão pela qual muitas vezes um arquivo de texto é usada
.Assumindo uma máquina (32-bit), onde sizeof (int) == 4 (e CHAR_BITS == 8), então você pode armazenar 4 bytes que são todos zero no local do arquivo atual usando o formato nativo, então o que você' tenho lá deve funcionar, eu acho. Você pode experimentar com outros valores como 0x01020304, você verá o layout byte em sua máquina.
É claro que você precisa ser cuidadosa leitura de volta, invertendo o procedimento utilizado para a escrita. E não se esqueça de reposicionar o arquivo antes de tentar re-ler os dados apenas por escrito.