return the printable form of a character

S

Sam Halliday

i want to have a function which can print the printable form (possibly a 2
character string) of a character on UNIX like systems. for example, if i were to
pass the ascii value '\3', i would like it printed "^C".

there is a file called charset.c in the distribution of less
[ftp://ftp.gnu.org/gnu/less/less-382.tar.gz] which achieves this, but it is
quite long winded and i do not wish to have to copy all the relevant code, as it
is longer than my program which requires this functionality.

i was wondering if anyone knew of a much smaller implementation... preferably
already in a GNU library?
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
i want to have a function which can print the printable form (possibly a
2 character string) of a character on UNIX like systems. for example, if
i were to pass the ascii value '\3', i would like it printed "^C".

The idiomatic response to your question is:

"Do it yourself and post your ISO-C code if you are stuck."
 
T

Thomas Matthews

Sam said:
i want to have a function which can print the printable form (possibly a 2
character string) of a character on UNIX like systems. for example, if i were to
pass the ascii value '\3', i would like it printed "^C".

there is a file called charset.c in the distribution of less
[ftp://ftp.gnu.org/gnu/less/less-382.tar.gz] which achieves this, but it is
quite long winded and i do not wish to have to copy all the relevant code, as it
is longer than my program which requires this functionality.

i was wondering if anyone knew of a much smaller implementation... preferably
already in a GNU library?

Using the ASCII table, there are two sets of nonprintable
characters: 0 .. 0x1F and 0x7F. Let us ignore the last one.
The set 0x00 .. 0x1F is known as control characters. Each one
has been related to pressing the CTRL key and a character,
such as 0x04 == CTRL-D. The "CTRL-" part is often replaced
with the '^' [caret] character.

So, if the value is less than 27, use ^ and a capital letter.
I believe ^@ represents 0x00. Try adding 0x40 to the value
to obtain the character part:
printf("^%c", value + 0x40);
or
printf("%c%c", '^', value + 0x40);
Note that this only applies to the ASCII chart. All other
encodings may not work.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
D

Darrell Grainger

i want to have a function which can print the printable form (possibly a
2 character string) of a character on UNIX like systems. for example, if
i were to pass the ascii value '\3', i would like it printed "^C".

there is a file called charset.c in the distribution of less
[ftp://ftp.gnu.org/gnu/less/less-382.tar.gz] which achieves this, but it
is quite long winded and i do not wish to have to copy all the relevant
code, as it is longer than my program which requires this functionality.

Roll your own. Have a look at the isprint function. If isprint is true
then just print it. If not then set a rule for converting it. For example,
check is c+'A' is printable. If yes, print '^' then c+'A'.

If you are having trouble with the code post it here.
i was wondering if anyone knew of a much smaller implementation... preferably
already in a GNU library?

Not I.
 
S

Sam Halliday

Emmanuel said:
The idiomatic response to your question is:

"Do it yourself and post your ISO-C code if you are stuck."

for what its worth... heres what i ended up doing (in the context of an
example). it only works for iso-8859 character maps, but thats all i need it
for. this is handy code to check and see what graphs are in your current console
fonts.

#include <stdio.h>
#include <stdlib.h>

/* http://en.wikipedia.org/wiki/Control_character */
char asciicntrl[][4]={
"NUL","SOH","STX","ETX","EOT","ENQ","ACK","BEL","BS","HT",
"LF","VT","FF","CR","SO","SI","DLE","DC1","DC2","DC3","DC4",
"NAK","SYN","ETB","CAN","EM","SUB","ESC","FS","GS","RS","US"};
char isocntrl[][5]={
"PAD","HOP","BPH","NBH","IND","NEL","SSA","ESA","HTS","HTJ",
"VTS","PLD","PLU","RI","SS2","SS3","DCS","PU1","PU2","STS",
"CCH","MW","SPA","EPA","SOS","SGCI","SCI","CSI","ST","OSC","PM","APC"};

void printablechar(char c);

main()
{
char i,n;

for (i=0,n=1;i<255;i++,n++){
printf("%d\t",i);
printablechar(i);
printf("\t");
if(7==n){
printf("\n");
n=0;
}
}
printf("\n");

return 0;
}

void printablechar(char c)
{
/* ASCII control sequences */
if (127==c)
printf("DEL");
else if (32>c)
printf("%s",asciicntrl[c]);

/* ISO-8859 control sequences */
else if ((127<c)&&(160>c))
printf("%s",isocntrl[c-128]);

/* printable characters */
else
printf("%c",c);
}
 
S

Sam Halliday

Sam said:
for what its worth... heres what i ended up doing (in the context of an
example). it only works for iso-8859 character maps, but thats all i need it
for. this is handy code to check and see what graphs are in your current
console fonts.

well... seems i broke x86 with that. for completeness here is the version you
should use, if you are interested:

#include <stdio.h>
#include <stdlib.h>

/* http://en.wikipedia.org/wiki/Control_character */
char asciicntrl[32][4] =
{ "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT",
"LF", "VT", "FF", "CR", "SO", "SI", "DLE", "DC1", "DC2", "DC3", "DC4",
"NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
};
char isocntrl[32][5] =
{ "PAD", "HOP", "BPH", "NBH", "IND", "NEL", "SSA", "ESA", "HTS", "HTJ",
"VTS", "PLD", "PLU", "RI", "SS2", "SS3", "DCS", "PU1", "PU2", "STS",
"CCH", "MW", "SPA", "EPA", "SOS", "SGCI", "SCI", "CSI", "ST", "OSC", "PM",
"APC"
};

void printablechar (unsigned char c);

int
main ()
{
int i, n;

for (i = 0, n = 1; i < 256; i++, n++)
{
printf ("%d\t", (unsigned char) i);
printablechar ((unsigned char) i);
printf ("\t");
if (7 == n)
{
printf ("\n");
n = 0;
}
}
printf ("\n");

return 0;
}


void
printablechar (unsigned char c)
{
/* ASCII control sequences */
if (127 == c)
printf ("DEL");
else if (32 > c)
printf ("%s", asciicntrl[(int) c]);

/* ISO-8859 control sequences */
else if ((127 < c) && (160 > c))
printf ("%s", isocntrl[(int) (c - 128)]);

/* printable characters */
else
printf ("%c", c);
}
 
E

Emmanuel Delahaye

Come on, be proud of yourself. You've done the job.
printf ("%d\t", (unsigned char) i);

"%d" expects an int. The cast is useless.

Sounds to be correct but not portable C, and to do the job. What was your
question again ?
 
S

Sam Halliday

Emmanuel said:
"%d" expects an int. The cast is useless.

yeah, wasn't thinkin right
Sounds to be correct but not portable C, and to do the job. What was your
question again ?

i basically wanted to know if a (standard) function existed that does what my
printablechar() does. mine is limited to iso-8859 charsets, a standard function
would supposedly support all charsets.
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
yeah, wasn't thinkin right


i basically wanted to know if a (standard) function existed that does
what my printablechar() does. mine is limited to iso-8859 charsets, a
standard function would supposedly support all charsets.

No. There is not such a function. If there was one, I guess it would
only support the charset of the implementation.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top