Read binary file with line delimeter - Page 5
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 5 of 11 FirstFirst ... 2345678 ... LastLast
Results 61 to 75 of 156

Thread: Read binary file with line delimeter

  1. #61
    Join Date
    Oct 2013
    Posts
    63

    Re: Read binary file with line delimeter

    I've added
    Code:
    #include <sstream>
    and works now.

    Actually, the it prints faster the output!

    Thanks again

  2. #62
    Join Date
    Oct 2013
    Posts
    63

    Re: Read binary file with line delimeter

    Hello 2kaud,

    Having the blocks in a single string I was able to print 2 parameters for each block. Parameter 2 is fine
    since I need to print it literaally, but for first one I need to convert it to decimal.

    I've added the lines in red to main function but is not converting to decimal the first 6 numbers (3 bytes).

    Code:
    int main()
    {
    FileFields	ff;
    bVec	bv;
    int blk = 0;
    string block;
    stringstream ss;
    unsigned int x; 
    
    	if (!ff.open("binary.txt")) {
    		cout << "Cannot open file!" << endl;
    		return 1;
    	}
    
    	while (ff.getField(bv)) {
    		conString(bv, block);
    		ss << hex << block.substr(0,6);
    		ss >> x; 		
    		cout << x << ","<< block.substr(6,16) <<endl;		
    	}
    
    	return 0;
    }
    Thanks for any suggestion again.

  3. #63
    Join Date
    Feb 2013
    Location
    Canada
    Posts
    51

    Re: Read binary file with line delimeter

    Not sure how you expect an unsigned int to hold a decimal value. But why do you have hex in there to pipe the data to the stringstream though? What's the point? A number is a number, you can format it to hex when you display that number as a string at a later time.
    Last edited by AceInfinity; October 18th, 2013 at 06:30 PM.

    Microsoft MVP .NET Programming (2012 - Present)
    ®Crestron DMC-T Certified Automation Programmer

  4. #64
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,558

    Re: Read binary file with line delimeter

    You mean like this

    Code:
    int main()
    {
    FileFields	ff;
    
    	if (!ff.open("binary.txt")) {
    		cout << "Cannot open file!" << endl;
    		return 1;
    	}
    
    bVec	bv;
    
    	for (int blk = 0; ff.getField(bv); blk++) {
    		cout << "block " << blk << endl;
    		//display(bv);
    		string block;
    
    		conString(bv, block);
    
    		istringstream iss(block.substr(0, 6));
    		unsigned long int x = 0;
    
                    iss >> hex >> x;
    		cout << x << ","<< block.substr(6,16) <<endl;	
    	}
    
    	return 0;
    }
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  5. #65
    Join Date
    Oct 2013
    Posts
    63

    Re: Read binary file with line delimeter

    Hello 2kaud,

    Exactly. It works just fine. Thanks for the correction. I know a new function to operate on strings now.

    What I have now replaces the use of first regex I posted in previous post, I'll try to follow thinking how to get the second pattern
    if I not able to do it by regex.

    I have this now:
    Code:
    int main()
    {
    FileFields	ff;
    	if (!ff.open("binary.txt")) {
    		cout << "Cannot open file!" << endl;
    		return 1;
    	}
    
    bVec	bv;
    	for (int blk = 0; ff.getField(bv); blk++) {
    		string block;
    		conString(bv, block);
    		istringstream iss(block.substr(0, 6));
    		unsigned long int x = 0;
    
                    iss >> hex >> x;
    		cout << x << ","<< block.substr(6,16)<< "," << block.substr(22,16) <<endl;	
    	}
    	return 0;
    }
    Question: How to begin the loop from block 1? I have changed the "for loop" from blk=1, but still prints block 0. I don't need to process the block 0.

    Thanks again
    Last edited by Philidor; October 18th, 2013 at 08:39 PM. Reason: Question

  6. #66
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,558

    Re: Read binary file with line delimeter

    ff.getField() will always return the blocks starting from block 0. If you don't want to process a particular block, just ignore it in the loop.

    Code:
    	for (int blk = 0; ff.getField(bv); blk++) {
    		if (blk == 0) continue;
    
    		cout << "block " << blk << endl;
               ......
            }
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  7. #67
    Join Date
    Oct 2013
    Posts
    63

    Re: Read binary file with line delimeter

    Hello 2kaud,

    Thanks for that. It works. I'm learning each time.

    I was able to work in VisualStudio with regex and I've been able to use regex and obtain almost the output I want, the code below is having one of the blocks in str variable, now I'd like to convert this code in a function.

    The code it works using "cout", but instead of print, I want to store each cout print in a variable in order to return this unique string(outstr) to main function. So main function would look like this:
    Code:
    	for (int blk = 0; ff.getField(bv); blk++) {
    		if (blk == 0) continue;
    		string block;
    		string outstr; //New output string taken as input the string "block"
    		conString(bv, block);
                    //Give block as entry string to new function OutStr and receive outstr as ouput string.
    		OutStr(block,outstr);
    		
    		cout << outstr << endl;
    	}
    The code I've been working with regex and works and which I'd like to convert in OutStr function is:
    Code:
    #include "stdafx.h"
    #include <iostream>
    #include <string> //Only to pause display in Visual Studio
    #include <regex>
    #include <sstream>      // std::ostringstream
    
    using namespace std;
    
    int main()
    {
    	string str(
    		"00000253206445018934551f81474554768fffff0015000a4800015a000242000160000133000136"
    		"00013700015b00016600016500017700017800017e00016900006a00007900009300012200002100"
    		"010900010a00012600010200010400010500010600011000010800012b00002c00012d00012e0001"
    		"5500015600072a00002f0000300000310000ff7900800932c90688888000a000800935c906000080"
    		"00000080093cc906888880008000800943c90688888000800005900f0102000000308147526905ff"
    		"ffff00910f01020000013a81475269559fffff009310010c0000009f8147526905ffffff0101960f"
    		"010e000000eb81475269596fffff00970f01010006f69981475269563fffff00940e000100000100"
    		"0100ffff0000010195060003790001ea058200370601000001006500000002000002001800000003"
    		"00000300170000000400000400010000000500000500150000000a00ffff006500000007802ec918"
    		"009181475269539fffffff009181475269539fffff000103ca030808fecb0a000000000000000000"
    		"00cc0101811bc90b009181475269567fffffffca06000000000000cb0103cc0101");
    
    	regex re1("(.{6,18})(532064[^f]*).(814[^f]*)");
    	regex re2("ff79(0080.{4}c906)?(.*)?05(9.{32,34}(.*)?)940e(.{28})");
    	regex re3("(9[0-367a-b])([0-9][0-9a-f]|0[e-f]|0[1-9a])(0[0-9a])(..)(.{8})([^f]*)(f*)?(0[0-1])(0[0-1])?");
    
    	smatch m;
    	smatch n;
    
    	regex_search(str, m, re1); //Search regex1
    	unsigned long int p1;
    	stringstream s1;
    	s1 << hex << m[1];
    	s1 >> p1;
    	cout << p1 << "|" << m[2] << "|" << m[3]; //Instead of print I want to append in a variable
    
    	regex_search(str, n, re2); //Search regex2
    	string p2;
    	stringstream s2;
    	s2 << n[3];
    	s2 >> p2;
    
    	//Iterate to match all occurrences of regex3 in string "h"
    	regex_iterator<string::iterator> rit(p2.begin(), p2.end(), re3);
    	regex_iterator<string::iterator> rend;
    
    	//ptrdiff_t const match_count(distance(sregex_iterator(p2.begin(), p2.end(), re3),sregex_iterator()));
    
    	unsigned int p3;
    	int lim;
    	while (rit != rend) {
    		if (rit->str(9) != ""){
    			lim = 9;
    		}
    		else{
    			lim = 8;
    		}
    
    		cout << "|";  //Instead of print I want to append in a variable
    		for (int i = 4; i <= lim; i++){
    			stringstream s3;
    			if (i != 6 && i != 7 && i < lim){
    				s3 << hex << rit->str(i);
    				s3 >> p3;
    				cout << p3 << ","; //Instead of print I want to append in a variable
    			}
    			else if (i == 6){
    				cout << rit->str(i) << ",";  //Instead of print I want to append in a variable
    			}
    			else if (i != 7 && i == lim){
    				s3 << hex << rit->str(i);
    				s3 >> p3;
    				cout << p3; //Instead of print I want to append in a variable
    			}
    		}
    		++rit;
    	}
    	//split by byte group 5 of regex2
    	string h1;
    	stringstream s10;
    	s10 << n[5];
    	s10 >> h1;
    
    	unsigned int j11;
    
    	for (int j = 0; j <= h1.size() / 2 - 1; j++){
    		cout << "|";  //Instead of print I want to append in a variable
    		stringstream s11;
    		s11 << hex << h1.substr(2 * j, 2);
    		s11 >> j11;
    		cout << j11; //Instead of print I want to append in a variable
    	}
    
    	//Only to pause display in Visual Studio
    	string var;
    	getline(cin, var);
    	///////////////////////////////////////////////////
    }
    Thanks in advance for any help.
    Last edited by Philidor; October 19th, 2013 at 03:49 PM.

  8. #68
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,558

    Re: Read binary file with line delimeter

    You're almost got it. You can convert a string stream to a string by using .str(). So if you have a string called outstr, you can do outstr += s3.str() etc. With strings, you can use + to concatenate several strings and use += to append to an existing string so

    Code:
    stringstream s1;
    	s1 << hex << m[1];
    	s1 >> p1;
    	cout << p1 << "|" << m[2] << "|" << m[3];
    becomes
    Code:
    stringstream s1;
         s1 << hex << m1 << "|" << m[2] << "|" << m[3];
         outstr += s1.str();
    and similar for the other places you want to append to a string variable.

    OutStr will be defined as

    Code:
    void OutStr(const string& block, string & outstr)
    {
    ....
    }
    with the body taken from your test main function.
    Last edited by 2kaud; October 19th, 2013 at 06:08 PM.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  9. #69
    Join Date
    Oct 2013
    Posts
    63

    Re: Read binary file with line delimeter

    Thanks one more time 2kaud,

    I've tested like you say in the way below:
    Code:
    	stringstream s1;
    	s1 << hex << m[1] << "|" << m[2] << "|" << m[3];
    	outstr += s1.str();
    It works almost the same but I'm nt sure why with this construction m[1] is not converted to decimal, for example, "000002" remains the same in the output when I'd like only "2".

  10. #70
    Join Date
    Oct 2013
    Posts
    63

    Re: Read binary file with line delimeter

    Hello 2kaud,

    I could fix the printing to decimal values.

    Now I don't know why is giving error out of range.

    The code with new function and main function is:
    Code:
    void OutString(const string& str, string & outstr) {
    	regex re1("(.{6,18})(532064[^f]*).(814[^f]*)");
    	regex re2("ff79(0080.{4}c906)?(.*)?05(9.{32,34}(.*)?)940e(.{28})");
    	regex re3("(9[0-367a-b])([0-9][0-9a-f]|0[e-f]|0[1-9a])(0[0-9a])(..)(.{8})([^f]*)(f*)?(0[0-1])(0[0-1])?");
    
    	smatch m;
    	smatch n;
    
    	regex_search(str, m, re1); //Search regex1
    	unsigned long int p1;
    	stringstream s1;
    	s1 << hex << m[1];
    	s1 >> p1;
    	outstr += to_string(p1) + "|" + m[2].str() + "|" + m[3].str();
    
    	regex_search(str, n, re2); //Search regex2
    	string p2;
    	stringstream s2;
    	s2 << n[3];
    	s2 >> p2;
    
    	//Iterate to match all occurrences of regex3 in string "h"
    	regex_iterator<string::iterator> rit(p2.begin(), p2.end(), re3);
    	regex_iterator<string::iterator> rend;
    
    	//ptrdiff_t const match_count(distance(sregex_iterator(p2.begin(), p2.end(), re3),sregex_iterator()));
    
    	unsigned int p3;
    	int lim;
    	while (rit != rend) {
    		if (rit->str(9) != ""){
    			lim = 9;
    		}
    		else{
    			lim = 8;
    		}
    
    		outstr += "|";
    
    		for (int i = 4; i <= lim; i++){
    			stringstream s3;
    			if (i != 6 && i != 7 && i < lim){
    				s3 << hex << rit->str(i);
    				s3 >> p3;
    				outstr += to_string(p3) + ",";
    			}
    			else if (i == 6){
    				outstr += rit->str(i) + ",";
    			}
    			else if (i != 7 && i == lim){
    				s3 << hex << rit->str(i);
    				s3 >> p3;
    				outstr += to_string(p3);
    			}
    		}
    		++rit;
    	}
    	//split by byte group 5 of regex2
    	string h1;
    	stringstream s10;
    	s10 << n[5];
    	s10 >> h1;
    
    	unsigned int j11;
    
    	for (int j = 0; j <= h1.size() / 2 - 1; j++){
    		outstr += "|";
    
    		stringstream s11;
    		s11 << hex << h1.substr(2 * j, 2);
    		s11 >> j11;
    		outstr += to_string(j11);
    	}
    }
    
    int main()
    {
    	FileFields	ff;
    	if (!ff.open("binary.txt")) {
    		cout << "Cannot open file!" << endl;
    		return 1;
    	}
    
    	bVec	bv;
    	for (int blk = 0; ff.getField(bv); blk++) {
    		if (blk == 0) continue;
    		string block;
    		string outstr;
    		conString(bv, block);
    
    		OutString(block, outstr);
    		cout << outstr << endl;
    	}
    	//Only to pause display in Visual Studio
    	string name;
    	getline(cin, name);
    	///////////////////////////////////////////////////
    	return 0;
    }
    I continue seeing what happens

  11. #71
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,558

    Re: Read binary file with line delimeter

    As I haven't got regex, I can't test and see what is going on. What line is giving the error?
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  12. #72
    Join Date
    Apr 1999
    Posts
    27,434

    Re: Read binary file with line delimeter

    Quote Originally Posted by Philidor View Post
    Now I don't know why is giving error out of range.
    Your code just assumes that strings and containers have at least n items without checking if this is the case. For example:
    Code:
    s1 << hex << m[1];
    s1 >> p1;
    outstr += to_string(p1) + "|" + m[2].str() + "|" + m[3].str();
    What if m is empty? What if it has less than 4 items (or 3 items)? What would happen if you attempt to access something that isn't there?
    Code:
    s2 << n[3];
    What if n had less than 4 items in it? That n[3] would not be legal.
    Code:
    if (rit->str(9) != ""){
    I don't know what str() is, but from the looks of it, the argument seems to be an index of some sort. If so, what if there are less than 9 items in str()?

    An out of range error is usually caused by doing just that -- accessing an item that is out of the range of available items. Your code is susceptible to this since it doesn't check for these things.

    Also, you should step through the code with the debugger, and see where the program breaks down. That should be what you're doing while you're writing this program. You can't write programs if you aren't able to debug them.

    Regards,

    Paul McKenzie

  13. #73
    Join Date
    Oct 2013
    Posts
    63

    Re: Read binary file with line delimeter

    Hello 2kaud and Paul,

    Thanks for the comments and help.

    I've been testing and I added some if statement in order to check if searched pattern exists, and now I don't get the error.

    My issue now is that when I execute the program it runs very slow even if I disable the function that processes each block with regex (OutString). Running the program with the same binary I posted and without using the regex function it prints each block slow .

    I'm attaching the program.exe and the source code I have so far.

    I don't know if the info that is printed when compile or when debug could help to make it faster.

    This is what I get.
    When Compile
    Code:
    1>------ Build started: Project: ReadBlockFromBinary, Configuration: Debug Win32 ------
    1>  Skipping... (no relevant changes detected)
    1>  ReadBlockFromBinary.cpp
    ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
    When run debug
    Code:
    'ReadBlockFromBinary.exe' (Win32): Loaded 'C:\Users\Philidor\Documents\Visual Studio 2013\Projects\ReadBlockFromBinary\Debug\ReadBlockFromBinary.exe'. Symbols loaded.
    'ReadBlockFromBinary.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. Cannot find or open the PDB file.
    'ReadBlockFromBinary.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel32.dll'. Cannot find or open the PDB file.
    'ReadBlockFromBinary.exe' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. Cannot find or open the PDB file.
    'ReadBlockFromBinary.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcp120d.dll'. Cannot find or open the PDB file.
    'ReadBlockFromBinary.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcr120d.dll'. Cannot find or open the PDB file.
    The program '[3332] ReadBlockFromBinary.exe' has exited with code 0 (0x0).
    PS: To test the program, the binary.txt must be located in C:\.

    Thanks in advance.
    Attached Files Attached Files

  14. #74
    Join Date
    Apr 1999
    Posts
    27,434

    Re: Read binary file with line delimeter

    Quote Originally Posted by Philidor View Post
    My issue now is that when I execute the program it runs very slow
    Never time a Debug build. You must build a Release version and see what happens. According to your screenshot, you're building/running debug builds, and debug builds by their very nature are slow. Build a release version.

    Second, you shouldn't be timing screen I/O, only raw processing. Remove the calls to write to the screen and then time things to see how long it takes to finish (and again, time a Release build, not Debug build).

    Regards,

    Paul McKenzie

  15. #75
    Join Date
    Oct 2013
    Posts
    63

    Re: Read binary file with line delimeter

    Hello Paul,

    You're correct. Thank you. I only did build (F7) and when I execute that *.exe file it runs faster. What I still see is that the last block it tooks more time to be processed. I think is because the last block contain a lot of filling zeros not only the bytes that really belongs to last block.

    How can be modified the conString function in order to stop when end of file is reached? the end of file is the sequence FF 78.

    Another question:
    Where should be removed the calls to the screen within visual c++ project? in the source code or is there some other files that automatically creates visual studio to print on screen?

    Thanks in advance.
    Last edited by Philidor; October 21st, 2013 at 11:51 PM. Reason: question

Page 5 of 11 FirstFirst ... 2345678 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center