Print unknown file format to screen - c++

I got a test file from a robot, I have to program by a C++ program I'm developing. So I wanted to use this file to see how the robot saves the coordinates of points. My program is currently able to calculate coordinates, now I have to generate the robot code.
Therefore I wanted to have a look at the file. But it seems that the file is writen in a binary mode. So my first idea was: Open the file in binary mode and print the content to the screen. So this is the code I'm using:
//#include "stdafx.h"
#include <iostream> // std::cout
#include <fstream> // std::ifstream
#include <Windows.h>
int main () {
std::ifstream is ("Test.PRG", std::ifstream::binary);
if (is) {
// get length of file:
is.seekg (0, is.end);
int length = is.tellg();
is.seekg (0, is.beg);
char * buffer = new char [length];
std::cout << "Reading " << length << " characters... ";
// read data as a block:
is.read (buffer,length);
if (is)
std::cout << "all characters read successfully.";
else
std::cout << "error: only " << is.gcount() << " could be read";
is.close();
// ...buffer contains the entire file...
for(int i=0; i<length; i++)
{
std::cout << (double) buffer[i] << std::endl;
}
delete[] buffer;
}
Sleep(10000);
return 0;
}
But with this code I just can't see what is writen in the file. I also tried different conversations than (double). I used char, int and float. Now I just don't know, what i could do more. Is there a possible methode to read this file and convert it to ASCII? I'm also adding the link for the file here, so you can have a look at it.
Download link for file

Here's a picture of the beginning of your file that I took with HexFiend:

Related

How to read back what I just wrote to a file?

I've been trying to write a program to open a file in both read and write mode:
#include <fstream>
#include <iostream>
using namespace std;
int main(){
fstream obj;
obj.open("hello.txt",ios::in|ios::out);
if (!obj){
cout << "File not opened" <<endl;
return 1;
}
obj << "Hi How are you" ;
char c;
while (!obj.eof()){
obj.get(c);
cout << c;
}
obj.close();
return 0;
}
When I compile this program on Visual Studio Code on Windows, though the text "Hi how are you" is printed in the file, the contents of the file are not printed on my screen. Can someone tell me what might be the problem?
Resetting the position indicator with seekp to 0 helps, because both output and input indicators are set to the end of file after write operation (you can read them with tellp tellg).
obj << "Hi How are you" ;
obj.seekp(0);
char c;
while (!obj.eof()){
obj.get(c);
cout << c;
}
Considering avoiding using obj.eof(), you can e.g. read your file line by line:
std::string line;
std::getline(obj, line);
std::cout << line << std::endl;
or in the loop:
while (std::getline(obj, line)) // here std::basic_ios<CharT,Traits>::operator bool is used to check if operation succeeded
{
std::cout << line << std::endl;
}
You got two problems there: buffering and seek position.
Buffering:
When you write the text with obj << "Hi How are you, you just write it into the buffer and the text gets written into the file after flushing the buffer. You can adjust which buffer type you want to use. The easiest way is to write std::endl after your text if you use line buffering.
A better explaination is already here
Seek Position:
You are reading from the last position in your file. You have to manually change the read position to the first character in the file, then you are done.

C - Cannot read all characters when reading a file

I am currently working on a lossless compression algorithm using the Huffman technique.
I managed to compress the desired file, and save the compressed data to a file.
However, I am unable to correctly read what is recorded in this file. Preferably, I would like to store the contents of this file in a std::string.
Here is the content of this file:
00000L,1LP10LURD100LVRj1LLRQRER.Rm1LlRr1LiRe1000LpRdRn100Lv100LC1LARF1LIRNRbRcRa100Lo100Lh1Lx1LMRSRf1LgRqRs1LuRt
X6*ÃWØ¿¸u÷üwµS™’ð‚<)âóUO_mÁ9Õö/ë‰ÍÌ Ï-,SÁúÚâuçëðÒì`WVwÿƒüšÎ뉊?Âgÿ­PÞuâ[CßTø¸CJŸy™“Þ¸Ý{+1sü <Ï~÷øà·\#¾¯à禡ú±Õö/Þüºû"í+ª•tÊæ+Ó¸Ð÷Õ>.'¦º¾Åü
úá‡
lÀ•¥¸Äq/?03òØ2'>÷?>9»ŸtY®Ùyù„‰u®'^~¿Û‚sŸ–öŽ(wß°/ì–~+K*•O´ ÿV:âyšö¨oãúü:ÿhrkã[‹7çjëĶ†KßW›˜iSêj£ÓúÆÉ×ûoÆÉï\l ÜKª‘Úɬ®b]T«ÏÖ42+4­Ô2µ“í«Ç7•’Ðä×Æ·Ø÷+ìÊþ¸˜¡sü!xSC—7ëoÿø=_bÿÔÕG§ÃIöÕÐÊV¥:ÅÅ?]Yß„ËsòÖx×™øÞíàæÍÓ+˜¯~7Æ´
puQäöÕA}ÿ².Õ {vÓ+˜¯¾ÍÌ ŽÞ¹úb+
ç·ñd³óÿSUŸ
/ˆ®Œ|/õ}‹ñT`»áúüi|EuÄæçMSs’âóUOrßUSí
ïFòH{Tû8ð¹C«ì_ׯ?_†—ÄWÅæªöV’ŽÜc`>ö0Á‹þÚ8¡ß~ÃH;ÜÙ¸dY¿;þ8-\`ÈœûÜüÞþSS™Zäî#d÷®7Bûo}åʪ¿ŽŽ(wß°Òö?õø0¡¿¾¯àÕ׉hñÇ7·™­Û‚rþ[ª%«KÅ’ý_býCxBí럿‡
löàœ„õÄææ÷îªÃÜ0ëðaxSˆ¬C´êÿm¨³]¯À¦W1^§T_XË®â6OF÷l4Ž;¦¿æ{÷»y—úØ«äý°sºâ³JÝB7ƶ…öñ«&ksóâóUOB ‘9÷¹ùÅf•º†ë^¹,«Ì÷ïCIÏÖ0Áÿ¯Á¿žšç壂{é„Eë"í¡–VK{åSÈ-Êjs"+
*}œx_“Þ¸Þ[·[ŸjÃBµN[êª}¡}’ÏÖ4<…^+PÞ‡16kø¼Õ^‡&ÁÓO.UUülñªY/dÅÏð€þ7O·?X×.„4Ÿm]2¹Š÷’œO©ªOúš¨ôøiSìãÂülžõÆòؽºÜûPÞªrßUSí?Õ~lÜ­#_ÿ­%›ŠÃIÏÖ,ïèÁwÂü4©¯ö¨oéZÁœSøªÿA¸—XõÂòO$Ìþ¸Äq>Ú¹¿[ÞY¬‹µòÑÄrÄÙ¯r†…öáæl ™Ÿ{Ÿ›&²¹Œº‹þÙÄíæ_ëBõb}çÃb8"ZW^Òº©Vɬ®bp¨±í¿Ê¥Sí³¯pȳ~vÎü ï–çç\LP¹þÛBûpÆó7\LP¹þ‚<)dÖW1d¾ë싶‹5Ûo3
Here is the code I wrote to read its contents:
int main(){
int number_of_lines = 0;
std::string line;
std::ifstream myfile("my_file.txt.huff");
while (std::getline(myfile, line)){
++number_of_lines;;
std::cout << "line number: " << number_of_lines << " content: " << line << std::endl;
}
}
I also tried via this way:
int main(){
FILE *find = fopen("my_file.txt.huff", "r");
int ca;
while(EOF != (ca=fgetc(find)))
std::cout << (char)ca;
std::cout << std::endl;
}
Here is the console rendering for the first code given:
line number : 1 content : 00000L,1LP10LURD100LVRj1LLRQRER.Rm1LlRr1LiRe1000LpRdRn100Lv100LC1LARF1LIRNRbRcRa100Lo100Lh1Lx1LMRSRf1LgRqRs1LuRt
line number : 2 content :
line number : 3 content : X6*├WÏ┐©Øu¸³wÁSÖÆ­é<)Ô¾UO_m┴9ı÷/Ùë═╠ ¤-,S┴·┌ÔuþÙ­Êý`WVw â³
At every time I try to read this file the problem is repeated. Indeed, the methods I use do not allow me to read it entirely.
Why does this problem occur?
thank you in advance
N.B: I was able to test, without success, the solution provided by Cillié Malan in this post. I'm having trouble for converting from a std::wstringstream to a std::string correctly.
Here is a short example that opens the file in binary mode and reads the entire file into a std::vector<uint8_t>. (you can also use a std::array<uint8_t> if you like). You open the file, .seekg() to the end, get the number of bytes and create the vector with that number of bytes and then .read() the file into the vector.
The following takes the filename as the first argument and outputs the content in hex format (for large files, change the output before testing to limit what is dumped to stdout)
#include <iostream>
#include <fstream>
#include <vector>
int main (int argc, char **argv) {
if (argc < 2) { /* validate filename given as argument */
std::cerr << "error: insufficient arguments\n"
"usage: " << argv[0] << " filename.bin\n";
return 1;
}
/* open file in binary mode, position at-the-end */
std::ifstream f (argv[1], std::ios::binary | std::ios::ate);
if (!f.is_open()) /* validate file open for reading */
return 1;
size_t nbytes = f.tellg(); /* get number of bytes in file */
f.seekg (0); /* rewind */
std::vector<uint8_t> arr(nbytes); /* declare vector with adequate storage */
f.read(reinterpret_cast<char*>(&arr[0]), nbytes); /* read file into vector */
if (f.bad() || f.fail()) /* validate read */
return 1;
for (auto& i : arr) /* output results (limit for larger files) */
std::cout << std::hex << std::showbase << static_cast<uint32_t>(i) << " ";
std::cout.put ('\n');
}
Look things over and let me know if you have further questions. There are several ways to approach this.

edit: trouble checking if file is empty or not, what am I doing wrong?

Edit: changed my question to be more accurate of the situation
I'm trying to open up a text file (create it if it doesnt exist,open it if it doesnt). It is the same input file as output.
ofstream oFile("goalsFile.txt");
fstream iFile("goalsFile.txt");
string goalsText;
string tempBuffer;
//int fileLength = 0;
bool empty = false;
if (oFile.is_open())
{
if (iFile.is_open())
{
iFile >> tempBuffer;
iFile.seekg(0, iFile.end);
size_t fileLength = iFile.tellg();
iFile.seekg(0, iFile.beg);
if (fileLength == 0)
{
cout << "Set a new goal\n" << "Goal Name:"; //if I end debugging her the file ends up being empty
getline(cin, goalSet);
oFile << goalSet;
oFile << ";";
cout << endl;
cout << "Goal Cost:";
getline(cin, tempBuffer);
goalCost = stoi(tempBuffer);
oFile << goalCost;
cout << endl;
}
}
}
Couple of issues. For one, if the file exist and has text within it, it still goes into the if loop that would normally ask me to set a new goal. I can't seem to figure out what's happening here.
The problem is simply that you are using buffered IO streams. Despite the fact that they reference the same file underneath, they have completely separate buffers.
// open the file for writing and erase existing contents.
std::ostream out(filename);
// open the now empty file for reading.
std::istream in(filename);
// write to out's buffer
out << "hello";
At this point, "hello" may not have been written to disk, the only guarantee is that it's in the output buffer of out. To force it to be written to disk you could use
out << std::endl; // new line + flush
out << std::flush; // just a flush
that means that we've committed our output to disk, but the input buffer is still untouched at this point, and so the file still appears to be empty.
In order for your input file to see what you've written to the output file, you'd need to use sync.
#include <iostream>
#include <fstream>
#include <string>
static const char* filename = "testfile.txt";
int main()
{
std::string hello;
{
std::ofstream out(filename);
std::ifstream in(filename);
out << "hello\n";
in >> hello;
std::cout << "unsync'd read got '" << hello << "'\n";
}
{
std::ofstream out(filename);
std::ifstream in(filename);
out << "hello\n";
out << std::flush;
in.sync();
in >> hello;
std::cout << "sync'd read got '" << hello << "'\n";
}
}
The next problem you'll run into trying to do this with buffered streams is the need to clear() the eof bit on the input stream every time more data is written to the file...
Try Boost::FileSystem::is_empty which test if your file is empty. I read somewhere that using fstream's is not a good way to test empty files.

writing after reading using fstream

I am under the impression fstream objects in c++ can be used to both read and write, using the same stream.
I have successfully been able to first write to a stream and then read from it. If I however try to write to it again the file is not affected.
Here is a code example that successfully compiles on windows using MinGw:
int main()
{
std::string path="file.txt";
std::fstream fs(path.c_str());
int buffSize=100;
int bytesRead=0;
char* buffer=new char[buffSize];
fs.write("hello", 5);
fs.seekp(0, std::ios::beg);
fs.read(buffer, buffSize);
bytesRead=fs.gcount();
for(int i=0;i<bytesRead;i++) {std::cout << buffer[i];}
std::cout << "\n";
fs.clear();
fs.seekp(1, std::ios::beg);
fs.write("E", 1);
std::cout << "fail: " << fs.fail() << "\n";
delete[] buffer;
}
The initial content of "file.txt" was only:
AAAAAAA
And the program outputs:
helloAA
fail: 0
Looking at the file in a text editor after running the program shows that the final content is:
helloAA
The final writing of the "E" has not taken effect, why is this and how do I fix it?
EDIT:
I tried using fs.clear() before writing again as user 0x499602D2 suggested. Also added a line printing out whether the failbit or badbit has been set or not and updated the program output. The final file content stays the same however, the problem remains.
(more verbose answer from what I posted in comments on the question)
You need to call flush() on output stream objects (derived from ostream) in order for the data to actually be written on the output stream. More information on flush() is available on this c++ reference page.
This work in GCC 4.9.0 and VS2013.
Notes:
seekg is for move the read pointer
seekp is for move the write pointer
In the sample code in line fs.seekp(0, std::ios::beg); need to be seekg. There is no problem because the read pointer has not been move (there is no read until there).
Code:
#include <algorithm>
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char* argv[]) {
std::string path = "H:\\save.txt";
int buffSize = 100;
int bytesRead = 0;
char* buffer = new char[buffSize];
std::fstream fs(path.c_str());
fs.write("hello", 5);
fs.flush(); // flushing to disk file
fs.seekg(0, std::ios_base::beg); // moving the read pointer
fs.read(buffer, buffSize);
bytesRead = fs.gcount();
for (int i = 0; i < bytesRead; i++) {
std::cout << buffer[i];
}
std::cout << "\n";
fs.clear();
fs.seekp(1, std::ios::beg);
fs.write("E", 1);
fs.flush(); // flushing to disk file
std::cout << "fail: " << fs.fail() << "\n";
delete[] buffer;
return 0;
}
string data="";
string Newdata="New Data";
std::fstream output_file(fileName, ios::in| ios::out);
output_file >> data; //read Data
output_file.seekg( 0, ios::beg );//set point to zero
output_file<<Newdata<<"\n"; //write new Data
output_file.close();
once you read a file using fstream, tellg < read pointer > and tellp < write pointer > points to -1.
to be able to write again using fstream, just call fstream.clear() and it will reset read and write pointer to where it was before reading.
none of the solution posted above work but fstream.clear() works.

how to write and read points to binary file?

I've programmed a code in C++ of a ball that moves in the space (3D points). I have all its movements positions. I mean, all the path points it passed.
I have to write its all positions\points into a binary file and then read it in order to restore the movements\path. for example, if I move the ball up and right, I'll want to save all the positions it passed so then I can read them and draw the ball moves the same, restore its path.
I saw an example for binary file but it doesn't say much to me:
// reading a complete binary file
#include <iostream>
#include <fstream>
using namespace std;
ifstream::pos_type size;
char * memblock;
int main () {
ifstream file ("example.bin", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
size = file.tellg();
memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();
cout << "the complete file content is in memory";
delete[] memblock;
}
else cout << "Unable to open file";
return 0;
}
Does it create the file automatically? Then where? And what about writing and reading points (X,Y,Z) ? Should I write it through binary bytes? or as points and the file makes it binary..?
You can write a point (X,Y,Z) to a binary file separating coordinates e.g by colons, and points by semicolons:
int X=10, Y=12, Z=13;
ofstream outfile("points.bin", ios::binary);
if (!outfile)
cerr << "Could not open a file" << endl;
else
outfile << X << ','
<< Y << ','
<< Z << ';';