473,395 Members | 1,987 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

"Ascii" codes to Hex (again)

Hi all !

I've got a lot of feedback from (the always helpful) Jon Skeet on this
subject before. Dispite this I'm still not there - due to my own lack of
knowledge of course.

Anyway, I'm "talking to" different labelprinters. They got one thing in
common -> A char value above 127 must be written in the "dos way". The
best way to do this AFAIK is to use hex values. By reading hundreds of
messages in this group, I've come to the code below. It does not work
properly though. The result of this code is the hex value 0x0 followed
by the next two signs for the hex value.

If I just can get this to work, then I'm solved the (by far) largest
problem I've had porting my projects from Delphi.

Any help are greatly apprecitated

protected internal string StringToAscii(string s)
{
Encoding en = UTF8Encoding.GetEncoding(850);
byte[] codedBytes = en.GetBytes(s);
char[] codedChars = en.GetChars(codedBytes);

StringBuilder sb = new StringBuilder();
foreach (char c in codedChars)
{
int si = (int)c;
if (si > 127)
{
sb.AppendFormat("\0x{0:x2}",(int)c);
}
else
{
sb.AppendFormat("{0}",(char)si);
}
}
string newString = sb.ToString();
return newString;
}

--
Best wishes
Kai Bohli
Norway
kaiboe@online-no
Nov 16 '05 #1
6 6153
Kai Bøhli <ka***********@online.no> wrote:
I've got a lot of feedback from (the always helpful) Jon Skeet on this
subject before. Dispite this I'm still not there - due to my own lack of
knowledge of course.
Don't worry, we'll crack it :)
Anyway, I'm "talking to" different labelprinters. They got one thing in
common -> A char value above 127 must be written in the "dos way".
*Which* DOS way? Installed in different places, you'll need different
encodings. You may be able to leave that question for the moment though
- let's get it working with one particular encoding first...
The best way to do this AFAIK is to use hex values.
What exactly do you mean by "use hex values"? What bytes are you
expecting to send to the printer?
By reading hundreds of
messages in this group, I've come to the code below. It does not work
properly though. The result of this code is the hex value 0x0 followed
by the next two signs for the hex value.
Yes, it would...
If I just can get this to work, then I'm solved the (by far) largest
problem I've had porting my projects from Delphi.

Any help are greatly apprecitated

protected internal string StringToAscii(string s)
{
Encoding en = UTF8Encoding.GetEncoding(850);
First, change that to Encoding.GetEncoding(850);
You're not doing anything UTF8Encoding specific, or indeed doing
anything related to UTF-8 at all - the above gives the wrong
impression. It's not actually going to be causing any errors - just
confusion.
byte[] codedBytes = en.GetBytes(s);
char[] codedChars = en.GetChars(codedBytes);
What are you hoping to achieve with this pair of lines? All it will do
is convert characters which aren't in CodePage 850 to question marks,
if you're lucky. Your string will still contain the Unicode characters
you started off with.
StringBuilder sb = new StringBuilder();
foreach (char c in codedChars)
{
int si = (int)c;
if (si > 127)
{
sb.AppendFormat("\0x{0:x2}",(int)c);
}
else
{
sb.AppendFormat("{0}",(char)si);
}
}
string newString = sb.ToString();
return newString;
}


The string you return is going to be very odd, to be honest. By the
time you get to a stage dealing with encodings, you shouldn't be
dealing with strings - you should be dealing with bytes. How are you
sending the data to the printer in the end? *Something's* got to be
converting the text data to bytes, and *that's* where you want the
encoding to go.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #2
Hi again Jon !

Thanks a lot for your help again. It's really appreciated !
*Which* DOS way? Installed in different places, you'll need different
encodings. You may be able to leave that question for the moment though
- let's get it working with one particular encoding first...
I can tell the printer what code page it shall use - eg 850. I've tested
a lot of encodings though and it will only work if I send the char value
0x9b (155) in code page 850.

The best way to do this AFAIK is to use hex values.


What exactly do you mean by "use hex values"? What bytes are you
expecting to send to the printer?


The printer expects for instance 0x9b (155) or 0x8f (143).

The best way is to send it the same way that I send the CTRL+B code
(0x2). The code for this is :

string dmImperial = "\x02n"; // units in imperial measure

Now if I could do something in the same way of the above for each char
above value 127, I think the problem will be solved.
First, change that to Encoding.GetEncoding(850);

Ok, I'll do that !

--
Best wishes
Kai Bohli
Norway
kaiboe@online-no
Nov 16 '05 #3
Hi and thanks for your reply !
you can replace 'w' with your foreach variable
the returned string can then be slotted into the origonal string in place of your character (plus whatever formatting you need before hex numbers)

does that help?


No, it gave me a single number (4) istead of the intended hex value.
--
Best wishes
Kai Bohli
Norway
kaiboe@online-no
Nov 16 '05 #4
Kai Bøhli <ka***********@online.no> wrote:
Thanks a lot for your help again. It's really appreciated !
No problem.
*Which* DOS way? Installed in different places, you'll need different
encodings. You may be able to leave that question for the moment though
- let's get it working with one particular encoding first...


I can tell the printer what code page it shall use - eg 850.


Ah yes, I remember now.
I've tested
a lot of encodings though and it will only work if I send the char value
0x9b (155) in code page 850.
Right.
The best way to do this AFAIK is to use hex values.


What exactly do you mean by "use hex values"? What bytes are you
expecting to send to the printer?


The printer expects for instance 0x9b (155) or 0x8f (143).

The best way is to send it the same way that I send the CTRL+B code
(0x2). The code for this is :

string dmImperial = "\x02n"; // units in imperial measure


Well, that's okay for 0x02, because that's ASCII "start of text" too,
so it's Unicode start of text as well. I'm not sure where the 'n' fits
in the above though...
Now if I could do something in the same way of the above for each char
above value 127, I think the problem will be solved.


No, because the reason the above works is because you're talking about
the same Unicode character - character 2.

As I said before, by the time you need to worry about encodings, you
should only be dealing in bytes. If you want byte 150 to go to the
printer, you shouldn't be going through *character* 150 which is
probably something entirely different. Convert your string to a byte
array with the appropriate encoding, and that byte array is what you
should send to the printer.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #5
Hi again Jon !
As I said before, by the time you need to worry about encodings, you
should only be dealing in bytes. If you want byte 150 to go to the
printer, you shouldn't be going through *character* 150 which is
probably something entirely different. Convert your string to a byte
array with the appropriate encoding, and that byte array is what you
should send to the printer.


Ok, I've rewritten the code to do this
protected internal byte[] StringToAscii(string s)
{
Encoding en = Encoding.GetEncoding(850);
byte[] codedBytes = en.GetBytes(s);
return codedBytes;
}

And I've changed all the callers to expect a byte array.
But how do I write this to the memorystream which will be sendt to the
printerport. I mean, I'm using a StreamWriter to write all other text
(Coordinates etc. are written in plain text)

eg:
MemoryStream memStrm = new MemoryStream();
StreamWriter sw = new StreamWriter(memStrm);
sw.WriteLine("\x02ySE1");
// draw lines and boxes
sw.WriteLine(dmLineHead + "0171" + "0001" + "L" + "393" + "002");
sw.WriteLine(dmLineHead + "0233" + "0021" + "L" + "109" + "014");
sw.WriteLine(dmLineHead + "0261" + "0001" + "L" + "011" + "072");
....
....

I've tried to write the same data using a BinaryWriter, and then the
labelprinter just dumped everything out in binary code - no format or
normal text.

I'm off to vacation now (a week in the southern Norway), but would like
to say it again: I'm really greatful for all your help !!
--
Best wishes
Kai Bohli
Norway
kaiboe@online-no
Nov 16 '05 #6
Kai Bøhli <ka***********@online.no> wrote:
Hi again Jon !
As I said before, by the time you need to worry about encodings, you
should only be dealing in bytes. If you want byte 150 to go to the
printer, you shouldn't be going through *character* 150 which is
probably something entirely different. Convert your string to a byte
array with the appropriate encoding, and that byte array is what you
should send to the printer.
Ok, I've rewritten the code to do this
protected internal byte[] StringToAscii(string s)
{
Encoding en = Encoding.GetEncoding(850);
byte[] codedBytes = en.GetBytes(s);
return codedBytes;
}


Right. Apart from the name of the method, which I believe is
misleading, that's fine. Admittedly you could make it somewhat simpler
by just exposing a read-only encoding:

static readonly internal Encoding Encoding = Encoding.GetEncoding(850);

and then people could just call Encoding.GetBytes(s) without the need
for an extra method. Anyway, that's by-the-by.
And I've changed all the callers to expect a byte array.
But how do I write this to the memorystream which will be sendt to the
printerport.
Very easily indeed!

stream.Write(bytes, 0, bytes.Length);

Streams are specifically for binary data, so you're fine there.
I mean, I'm using a StreamWriter to write all other text
(Coordinates etc. are written in plain text)

eg:
MemoryStream memStrm = new MemoryStream();
StreamWriter sw = new StreamWriter(memStrm);
sw.WriteLine("\x02ySE1");
// draw lines and boxes
sw.WriteLine(dmLineHead + "0171" + "0001" + "L" + "393" + "002");
sw.WriteLine(dmLineHead + "0233" + "0021" + "L" + "109" + "014");
sw.WriteLine(dmLineHead + "0261" + "0001" + "L" + "011" + "072");
...
...
Okay. You can either keep the StreamWriter, but Flush it every time
you're then going to write directly to the stream, or call
StringToAscii on *everything*, or just give your StreamWriter the
correct encoding to start with:

StreamWriter sw = new StreamWriter(memStrm, Encoding.GetEncoding(850));

and it will take care of the encoding for you.
I've tried to write the same data using a BinaryWriter, and then the
labelprinter just dumped everything out in binary code - no format or
normal text.
BinaryWriter is almost certainly not the way to go here.
I'm off to vacation now (a week in the southern Norway), but would like
to say it again: I'm really greatful for all your help !!


No problem - hope it helps.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
by: - Steve - | last post by:
I've been given a school assignment and while everything else is easy there's one topic I'm completley lost on. I've been given an ASCII file that looks like this. During start-up, the program...
3
by: mr | last post by:
How can i 'force' c++ to interprete "blabla" strings as unicode string instead of ascii string (i just don't want to add 'L' before the thousands strings that are on my projects...), as all my...
5
by: Achim Domma | last post by:
Hi, I have to convert a string to its "best possible" ascii representation. It's clear to me that this is not possible or sense full for all unicode characters. But for most European characters...
8
by: jeffpierce12 | last post by:
Hello, I am trying to send some characters to a scanner that I have hooked up to the COM 1 port on my PC. I am running Linux operating system, and I have the following sample program: ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.