Share via


How to append to a string a value 0x00 "00" and not "\0" char

Question

Wednesday, March 25, 2015 1:50 PM

Hi,

I have an issue after  reading a prn file which contain  this binary string   "1b 41 00 1b 6d 05 00 00 00 1b 6d 01 ...."  with containing "00" bytes. When I try to copy them from a byte array to a string with Append() mode. The append methode is always making from 0x00 an '\0' char (end of string) and the append stops. The target is to copy the whole prn string vom file to a string, with containing all "00" bytes.

Here is a part of may code:

....

BinaryReader br = new BinaryReader(memStream);

char[] bin = br.ReadChars((int)(memStream.Length - memStream.Position));

long iLen = .....;

StringBuilder sb = new StringBuilder(FileLen);

for (long i = 0; i < iLen; i++)
   {
       if (bin[i] != 0x00)
            sb.Append(bin[i]);
       else
           sb.Append('\x00'); <=== ???????
   }

string str = sb.ToString();

Has anybody an idea to fix this problem.

Regards

Hubert

WinCE Forum

All replies (12)

Thursday, March 26, 2015 3:10 PM âś…Answered

Hi,

thank you for your suggestions. I have made a workaround here. I do not use a string for transfer data, I use simple a byteArray for this and changed the interface of my printer method congruent .

Now I can load prn file and print it out.

Regards

Hubert

WinCE Forum


Wednesday, March 25, 2015 2:15 PM

The character equivalent of 00 is \0.  What you are trying to do is treat binary values as chars and that isn't going to work out well if the data isn't printable characters.  If you are trying to take a string that is saved in a binary file then you first need to know what charset it was saved in (ASCII, Unicode, etc).  Once you know that then read the byte array in (you need to know how long the string is and that is determined by how it was originally saved). You really need to post how the string was written to the stream before we can help with how you should read it back.

Michael Taylor
http://blogs.msmvps.com/p3net


Wednesday, March 25, 2015 2:37 PM

Hi Michael,

thank you for answering.  I have load this prn file into Notepad++ and this show me "Encode in ANSI".  The shown character "1b 41 00 1b 6d 05 00 00 00 1b 6d 01 ...." are from Notepad++. The prn file is a standard file  from printing into a file.

Do yo have a sample for me, how I can read this correct ?

Regards

Hubert

WinCE Forum


Wednesday, March 25, 2015 3:00 PM

Read the data into a byte array based upon whatever length the string is.  Then use Encoding.ASCII.GetString to convert the byte array to the string equivalent.  MSDN has an example of how you would do this for a file stream.  A memory stream works similarly.

Michael Taylor
http://blogs.msmvps.com/p3net


Wednesday, March 25, 2015 4:26 PM

Hi Michael,

I tested your suggestion with Encoding.ASCII.GetString MSDN sample and all other Encoding options, without success. It's always same situation than before that "00" is '\0'

Failed output of Encoding.ASCII.GetString

"  1b 41 1b 6d 05 1b 41 1b 41 1b 6d 05 5c 30 5c 30 5c 30 1b 6d 01 1b 67 02 4f 5c 30 1b 51 16 3c 1b 51 03 19 1b 41 1b 6d 05 5c 30 1b 6d 03 1b 67 5c 30 1b 67 5c 30 1b 67 5c 30 1b 67 5c 30 1b 67 5c 30 1b 67 5c 30 1b 67 5c 30 1b 67 5c 30 1b 67 5c 30 1b 67 5c 30 1b 67 5c 30 1b 67 5c 30 1b 67...  "

What I need  is this:

"1b 41 1b 6d 05 1b 41 1b 41 1b 6d 05 00 00 00 1b 6d 01 1b 67 02 4f 00 1b 51 16 3c 1b 51 03 19 1b 41 1b 6d 05 00 1b 6d 03 1b 67 00 1b 67 00 1b 67 00 1b 67 00 1b 67 00 1b 67 00 1b 67 00 1b 67 00 1b 67 00 1b 67 00 1b 67 00 1b 67 00 1b 67 00 1b ...  "

You can test this if you print in a file and load this file.

Regards

Hubert

WinCE Forum


Wednesday, March 25, 2015 5:23 PM

To clarify, byte value 00 is the equivalent of '\0' so the conversion is correct.  What I cannot figure out is how you're making the jump from the contents of a PRN file (which isn't textual data) to a string?  A PRN file contains more than just arbitrary text that can be converted to a string.  It also contains the necessary printer codes to control printing.  As such simply taking the file and trying to convert it to a string simply won't work as you'd get both the printer commands and the textual data to print.  To get to the textual content of a file you'd need to parse the PRN file.

As an example, if you type Hello World into a text file and print it to PRN file then the first set of characters will be information about the printer.  You can convert that to text but only parts of the actual stream will show up as text.  The rest are binary codes.  This would include the 00s that you're seeing. The actual Hello World text doesn't even show up as it has been converted to a binary format that the printer can print out.

What exactly are you trying to get out of the PRN file?


Thursday, March 26, 2015 8:35 AM

Hi,

You are right,  one part are not printable chars (control commands) and the other printable chars ("Hello World").  But there must be a way in C# how I can load a prn file to a string variable ?  I have done this in c++ without problems. 

What I exactly want to do, is to load  a prn file  1:1  from file to a string that I can print out them.

Regards

Hubert   

WinCE Forum


Thursday, March 26, 2015 11:11 AM

there must be a way in C# how I can load a prn file to a string variable ?  I have done this in c++ without problems. 

What I exactly want to do, is to load  a prn file  1:1  from file to a string that I can print out them.

*>But there must be a way in C# how I can load a prn file to a string variable ?  *

I believe you've already been shown how.

>I have done this in c++ without problems.

Exactly *how* did you do it in C++?

Were you using std::string? Or std::wstring? Or System::String?

>What I exactly want to do, is to load  a prn file  1:1  from file to a string that I can print out them.

Bear in mind that in C# a "string" type is a System.String, which is a string of Unicode
characters - not bytes.

Do you expect to actually "print" this string? i.e. - Send to a printer?

Or by "print" do you mean write the string on the console?

With respect to 00 vs \0 they are the same, but which you *see* will depend on how you're
displaying that character. If you look at the string contents in the debugger, it will usually
show binary zero as \0 - but if you output the string to the console and redirect that to a
file (via > or >>) that same character will show as 00 in a hex viewer.

- Wayne


Thursday, March 26, 2015 11:51 AM

Hi Wayne,

about your questions:

1. Exactly *how* did you do it in C++?

Were you using std::string? Or std::wstring? Or System::String?

I get a LPWSTR pointer after CreateFile(), ReadFile() and MultiByteToWideChar();

2. Do you expect to actually "print" this string? i.e. - Send to a printer?

I send it directly via port to a printer. The printer needs this correct command and text bytes, otherwise it makes a hex dump print out.

So I need an equivalent solution in C#.

Regards

Hubert

WinCE Forum


Thursday, March 26, 2015 12:13 PM

I usually use code like below to convert bytes to a string.

            byte[] input = new byte[]{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
                                    0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
            string output = string.Join(" ", input.Select(x => x.ToString("X2")).ToArray());

jdweng


Thursday, March 26, 2015 1:48 PM

Hi,

thanks for sample. But sorry I have an issue that my platform is a  CE6.0 .NET CF 3.5 platform, this do not support the input.select() method. Do you have a sample for my platform ?

Regards

Hubert

WinCE Forum


Thursday, March 26, 2015 2:01 PM

That explains a lot.  LPWSTR is a pointer to a wide character array.  C++ does not have a byte type so we always use a char.  Hence a char array can be either a string or simply an array of bytes.  The only way to know for sure is to look at the usage.  In either case you can certainly treat the value as a string but in the case of a byte array it'll stop when it hits the NULL terminator. 

It is interesting that you used wide character as there is no guarantee that the byte data is actually long enough.  But you mentioned MultiByteToWideChar so it sounds like you're reading it as an ANSI string and then converting it to wide character.  The wide character conversion will stop when it hits a NULL terminator or the length you provided (if any).  Chances are you are providing the length so 00s are converted to NULLs.  Since you're converting to wide char the string itself (as far as C++ is concerned) isn't done until you have 2 NULLs.  Hence if you printed out the contents of the string you'd see most of the file contents but not all of it (probably) nor would it technically be completely correct.

It doesn't really make sense to me that you need the "text bytes" as all it is a stream of bytes either way.  The most that might be needed is that it is Unicode.  In that case you could use the Encoding.ASCII to convert the byte array to a string and then pass that along or you could convert it back to a byte array using Encoding.Unicode.GetBytes. 

Another alternative might be to simply send the entire file to the printer by using Process with the verb "print" and the file.  This would be equivalent to right-clicking the file and selecting Print.  If it works then Process would be easier.