Language…
13 users online: CalHal, crocodileman94,  Deeke, dubiousdinobot, Dzing, fanfan21, Hammerer, isaix, MegacesarCG, sheeptitan,  shovda, TheBourgyman, Ziz - Guests: 287 - Bots: 311
Users: 64,795 (2,378 active)
Latest user: mathew

C++ fsteam Binary mode help

Well, like most of my little itty bitty things I start with C++, they always involve Fstream.h, but my one little issue with it is how binary mode works exactly. AKA :
Code
#include <fstream>
#include <iostram>

int num=0;

main() {
cout<<"insert number\n";
cin>>num;
ofstream file;
file.open(file.bin, ios::binary)
file<<num;
}

What would file.bin contain? lets say I input 2. would it be 00000010? if so, what if the example became:
Code
#include <fstream>
#include <iostram>

char letter[20];

main() {
cout<<"insert phrase\n";
cin>>letter;
ofstream file;
file.open(file.bin, ios::binary)
file<<letter;
}

? would it convert it to ASCII and then to binary? Isn't that the same as text mode?
*WARNING: due to cosmic radiation, Quantum fluctuations, or earth going into sector x79352C, the world may end at any moment. Have a nice day.

Current Project:



Status:Complete

Previous project status: Failed/Quit

Current Issue

C++ : fsteam help



Binary mode doesn't spam 10100101010. The first file would contain "2", and the second would contain what you entered (not sure what happens if you enter something with spaces).
It's usually not a good idea to enable binary mode on a file containing text like this. Binary mode is mainly meant for ROMs and other files that uses a binary format.
The difference between binary mode and normal mode is that some character translations will occur in normal mode. For example, file<<"\n"; in normal would be the same as file<<"\r\n"; in binary mode. I think some whitespace-related stuff is also changed in normal mode.
My tutorial also suggests file.get();, file.put();, file.read();, and file.write(); in binary mode instead of >> and <<, but I'm not sure how strictly this is enforced.
Also, my compiler wouldn't like these codes, you forgot the "void" specifier for main(). I guess you're using another one.
<blm> zsnes users are the flatearthers of emulation
my compiler would kill me for that code too, but that isn't really necessary for this example. anyway, in my actual code, my issue was the <<'s and >>'s. so the file.reads/writes take 2 arguments.
Code
#include <fstream>
#include <iostram> 
int num=0; 
int main() 
{ 
cout<<"insert number\n"; 
cin>>num; 
ofstream file; 
file.open(file.bin, ios::binary) 
file.write((char*)&num, sizeof(num)); 
} 

but would you replace the (char*) with (int*) or must it be a char?

I also seem to have another issue. the GUI i'm using seems to have strings formatted as glib::ustring, but fstream wants a const char*, so how would that conversion take place? I've read something about std::strings having a c_str() member function, but I might be able to convert the glib::ustring into a std::string somehow.

Now the spaces in files are giving me issues. Can you somehow override the copy until a space way this works? like this:
Code
...
char Buffer[256];
...
ifstream file("file.txt");
int length = sizeof(file);

file.read(Buffer, length)


would it overide it or no?I currently use << and >> for text operations for the sake of convienience.
*WARNING: due to cosmic radiation, Quantum fluctuations, or earth going into sector x79352C, the world may end at any moment. Have a nice day.

Current Project:



Status:Complete

Previous project status: Failed/Quit

Current Issue

C++ : fsteam help



Originally posted by Pseudonym
ifstream file("file.txt");
int length = sizeof(file);

No no no. That sizeof() would return the size of an ifstream, not the size of the file.
This appears to be the correct method:
Originally posted by code
// read a file into memory
#include <iostream>
#include <fstream>
using namespace std;

int main () {
int length;
char * buffer;

ifstream is;
is.open ("test.txt", ios::binary );

// get length of file:
is.seekg (0, ios::end);
length = is.tellg();
is.seekg (0, ios::beg);

// allocate memory:
buffer = new char [length];

// read data as a block:
is.read (buffer,length);

is.close();

cout.write (buffer,length);

return 0;
}


And yes, you should be able to use a typecast on any pointer and use it as the first argument to an ofstream.write(). Your first example looks perfectly fine to me (assuming you want it to look like *Fx8 in e.g. Notepad).
<blm> zsnes users are the flatearthers of emulation
Thanks. so in
Code
// get length of file:
is.seekg (0, ios::end);
length = is.tellg();
is.seekg (0, ios::beg);

the seekg(0, ios::end) moves the read/write pointer to the end of the file, tellg() shows how many bytes into the file that is, and then the other seekg sets it back to the beginning? and the 0s in the seekg are the exact amount of bytes you want to move in addition to the starting locations the ioses give, correct? so if I just took a ridiculous ammount of bytes and put it in for the 2nd argument of the file.write(), it would read that my bytes regardless of spaces?
*WARNING: due to cosmic radiation, Quantum fluctuations, or earth going into sector x79352C, the world may end at any moment. Have a nice day.

Current Project:



Status:Complete

Previous project status: Failed/Quit

Current Issue

C++ : fsteam help



Yes, the 0's are offsets from what the ios::x means. There's a third command, ios::cur, that seeks relative to the current position.
And yes, binary mode doesn't count spaces/etc.

However, you're wrong at one place:
Quote
so if I just took a ridiculous ammount of bytes and put it in for the 2nd argument of the file.write(), it would read that my bytes regardless of spaces?

<blm> zsnes users are the flatearthers of emulation
Quote
so if I just took a ridiculous ammount of bytes and put it in for the 2nd argument of the file.write(), it would read that my bytes regardless of spaces?

That would segmentation fault (ie. crash); your program would attempt to read that many bytes from memory (and into the file) and then the OS would terminate it for attempting to access memory that it doesn't have permission to. That is, assuming the first argument is an invalid pointer or a pointer to some data that isn't as big as the size (second argument).

Code
file.write((const char*) 0xDEADBEEF, 32766); //segfault
char *somedata = new char[28];
file.write(somedata, 24000); //segfault, when it tries to read somedata + 28
delete somedata; //the program will never get here!


About the text vs binary modes, use text mode for files that will contain only text (TXT, HTML/XML, C/C++/C#/Java source files, etc...) and binary mode for everything else (ROMs, databases, image/sound/video files, archive files (ZIP/7z/RAR/TAR.GZ), etc...). What text mode does is convert C/C++ newlines ("\n", aka Line Feed (0x0A in Hex)) to and from DOS/Windows newlines ("\r\n", aka Carriage Return + Line Feed (0x0D0A in Hex)), or whatever the standard newline is on the operating system you are compiling for. This can create havoc when working with binary data, because if you write data containing the binary representation of a newline, it will mess it up.

If you are writing code for *nix operating systems (Linux, BSD, Solaris, OS X), and only *nix, binary mode and text mode do the exact same thing, as on those platforms, Line Feed is the native newline. However, on Windows, if you use binary mode to write text files, if you open up the text files in Notepad all newlines (\n) will show up as rectangles instead of new lines, and therefore the file will be one long line of text. (If you use Wordpad, or a decent text editor (eg Notepad++) it will read it just as it would have if you had written to the file in text mode, as these editors understand *nix newlines.) It's better to use text mode for text files for this reason.

Your layout has been removed.