I've tested, compiles without errors, but is not printing the content of the blocks, I only receive this.
Code:
V[0]=vEJXXYW1_D1211308071344S dE‰4Uÿw
This is the interpreted content before the first delimiter "ff77". I'm not sure what is happens. Maybe is not reading literally the bytes and because of that is not finding the FF77.
When I see in an hex editor, the first 64 bytes are the following:
Can you zip the first few thousand bytes of the file and post so I can take a look at it. I tried it on a test text file here I created that was over 1000 bytes and it showed the expected output.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
The delimeter is NOT "FF77". The delimeter is 0xFF77 - which is a different ball game! Also the data contains 0x00 which is usually used to indicate the end of a string. Basically the functions work with ASCII text not binary data. That's why they work fine with the test data but not with your actual binary file.
I'll have a look at the functions over the next few days.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
using namespace std;
typedef unsigned char BYTE;
typedef unsigned short int WORD;
typedef vector<BYTE> bVec;
#ifndef LOBYTE
#define LOBYTE(w) ((BYTE)((WORD)(w) & 0xff))
#endif
#ifndef HIBYTE
#define HIBYTE(w) ((BYTE)((WORD)(w) >> 8))
#endif
class FileFields
{
private:
ifstream ifs;
bool opened;
public:
FileFields() : opened(false) {}
~FileFields() {
if (opened)
ifs.close();
}
bool open(const char* name);
bool getField(bVec& field, WORD delim = 0xFF77);
};
bool FileFields::open(const char* name) {
ifs.open(name, ios::binary);
return (opened = ifs.is_open());
}
bool FileFields::getField(bVec& field, WORD delim)
{
char by;
bool cont = true;
field.clear();
if (!opened || !ifs.good())
return false;
for (ifs.get(by); cont && ifs.gcount(); ifs.get(by)) {
if (by == HIBYTE(delim))
if (ifs.peek() == LOBYTE(delim))
cont = false;
if (cont)
field.push_back(by);
}
return true;
}
void display(const bVec bv)
{
for (int i = 0; i < bv.size(); i++)
cout << setw(2) << setfill('0') << hex << (int)bv[i];
cout << endl << endl;
}
int main()
{
FileFields ff;
bVec bv;
if (!ff.open("binary.txt")) {
cout << "Cannot open file!" << endl;
return 1;
}
while (ff.getField(bv))
display(bv);
return 0;
}
Last edited by 2kaud; October 13th, 2013 at 02:28 PM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
Thanks for this help really. I'm testing and the code prints content of the binary correctly.
Now, I'm trying to print similarly each block, like block[0], block[1] etc like before, but I tried in dispaly function,
but I see now that function handles one byte at a time.
How can I print each block separately?
Thanks for your help, I'm trying to understand the way how you do it.
Display prints one block separated by line feeds. In the main program, the vector bv holds one block (data between 2 delimeters) from the file. So you can use the contents of the vector bv to process one block at a time. The class function getField returns a vector containing the contents of the next block each time it is called.
If you print to print a block heading before each block, try
Code:
int main()
{
FileFields ff;
bVec bv;
int blk = 0;
if (!ff.open("binary.txt")) {
cout << "Cannot open file!" << endl;
return 1;
}
while (ff.getField(bv)) {
cout << "block " << blk++ << endl;
display(bv);
}
return 0;
}
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
I'm not sure what happens, but trying in that way I receive "block 0" and in the next file the content of complete binary file. So, it seems like all content of the file is contained in block 0.
if (by == HIBYTE(delim))
if (ifs.peek() == LOBYTE(delim))
with
Code:
if ((BYTE)by == 0xff)
if ((BYTE)ifs.peek() == 0x77)
Is your type char default signed or unsigned? I have default unsigned. If yours is signed, that may be the problem.
UPDATE That is probably the problem. I changed my default to signed and got the same issue you have. Putting (BYTE) in the 2 if statements makes it work if default char is signed.
Last edited by 2kaud; October 13th, 2013 at 05:15 PM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
In main function I had to add "\n" in order to print in different row as below, I'm not sure if you need to do that to get the out you posted.
In function display, have you got the final cout << endl << endl; statement? I get blank lines between my blocks.
replacing the 2 if with (BYTE) makes it work! why?
Because if char is typed signed, it can never equal the value 0xff as any value over 127 (0x7f) is treated as negative, so a signed value compared to 0xff is always false! Using the (BYTE) cast, treats it as an unsigned number which can then be compared successfully to 0xff.
Last edited by 2kaud; October 13th, 2013 at 06:01 PM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
I would've taken a more generic approach, utilizing more function parameters instead of hardcoding everything in there...
Code:
void get_fields(const std::string& s, const std::string& find_str, std::vector<std::string>& vec)
{
if (s.find(find_str, 0) == std::string::npos) { vec.push_back(s); return; }
size_t index[2] = { 0, 0 };
const size_t len = find_str.length();
do
{
index[1] = s.find(find_str, index[0]);
if (!(x = s.substr(index[0], index[1] - index[0])).empty()) vec.push_back(x);
index[0] = index[1] + len;
} while (index[1] != std::string::npos);
}
int main(void)
{
const std::string find_str("FF77");
const std::string s("Test1FF77Test2FF77Test3FF77Some textFF77other textFF772");
std::vector<std::string> v;
get_fields(s, find_str, v);
for (unsigned i = 0; i < v.size(); i++)
std::cout << "v[" << i << "]=" << v[i] << std::endl;
return 0;
}
*edit: Wow, didn't even notice all of the other replies on the last page. I'll need to do more reading.
The delimeter as stated in my post #34 is 0xff77 and NOT "FF77". On previous pages we've already covered using string find which is not what is required when working with binary files.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
The delimeter as stated in my post #34 is 0xff77 and NOT "FF77". On previous pages we've already covered using string find which is not what is required when working with binary files.
No need for the criticism here. I don't see how hard it could be for somebody to change the function parameters around to be honest, although, my post served as an example... Perhaps you have neglected to read my edit?
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.