char as string

D

David RF

if someone finds it useful, a clean version:

#include <stdio.h>

static char ascii[] = {
0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,
0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,
0x0a,0x00,0x0b,0x00,0x0c,0x00,0x0d,0x00,0x0e,0x00,
0x0f,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,
0x14,0x00,0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,
0x19,0x00,0x1a,0x00,0x1b,0x00,0x1c,0x00,0x1d,0x00,
0x1e,0x00,0x1f,0x00,0x20,0x00,0x21,0x00,0x22,0x00,
0x23,0x00,0x24,0x00,0x25,0x00,0x26,0x00,0x27,0x00,
0x28,0x00,0x29,0x00,0x2a,0x00,0x2b,0x00,0x2c,0x00,
0x2d,0x00,0x2e,0x00,0x2f,0x00,0x30,0x00,0x31,0x00,
0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,
0x37,0x00,0x38,0x00,0x39,0x00,0x3a,0x00,0x3b,0x00,
0x3c,0x00,0x3d,0x00,0x3e,0x00,0x3f,0x00,0x40,0x00,
0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00,0x45,0x00,
0x46,0x00,0x47,0x00,0x48,0x00,0x49,0x00,0x4a,0x00,
0x4b,0x00,0x4c,0x00,0x4d,0x00,0x4e,0x00,0x4f,0x00,
0x50,0x00,0x51,0x00,0x52,0x00,0x53,0x00,0x54,0x00,
0x55,0x00,0x56,0x00,0x57,0x00,0x58,0x00,0x59,0x00,
0x5a,0x00,0x5b,0x00,0x5c,0x00,0x5d,0x00,0x5e,0x00,
0x5f,0x00,0x60,0x00,0x61,0x00,0x62,0x00,0x63,0x00,
0x64,0x00,0x65,0x00,0x66,0x00,0x67,0x00,0x68,0x00,
0x69,0x00,0x6a,0x00,0x6b,0x00,0x6c,0x00,0x6d,0x00,
0x6e,0x00,0x6f,0x00,0x70,0x00,0x71,0x00,0x72,0x00,
0x73,0x00,0x74,0x00,0x75,0x00,0x76,0x00,0x77,0x00,
0x78,0x00,0x79,0x00,0x7a,0x00,0x7b,0x00,0x7c,0x00,
0x7d,0x00,0x7e,0x00,0x7f,0x00
};
/* if x is not ascii returns pointer to first member (0) */
#define ctos(x) &ascii[((x) & ~0x7f) == 0 ? (x) * 2 : 0]

static char *dummy(int c);

static char *dummy(int c)
{
return ctos(c);
}

int main(void)
{
int c = 'a';

printf("%s %s %s %s\n", ctos(c), ctos('b'), dummy('c'), ctos(128));

return 0;
}
 
K

Keith Thompson

David RF said:
if someone finds it useful, a clean version:

#include <stdio.h>

static char ascii[] = {
0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,
0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00, [...]
0x78,0x00,0x79,0x00,0x7a,0x00,0x7b,0x00,0x7c,0x00,
0x7d,0x00,0x7e,0x00,0x7f,0x00
};
/* if x is not ascii returns pointer to first member (0) */
#define ctos(x) &ascii[((x) & ~0x7f) == 0 ? (x) * 2 : 0]

static char *dummy(int c);

static char *dummy(int c)
{
return ctos(c);
}

int main(void)
{
int c = 'a';

printf("%s %s %s %s\n", ctos(c), ctos('b'), dummy('c'), ctos(128));

return 0;
}

Just a couple of comments.

I'd add a "const" to the declaration of ascii, since you're not
going to change its value.

The desired behavior for characters outside the range 0..127 may
vary. It's easy enough to change this. For example, you can handle
full 8-bit character values (say, if you're dealing with Latin-1),
by doubling the size of the table and tweaking the macro definition.
 
P

Peter Nilsson

David RF said:
if someone finds it useful, a clean version:

#include <stdio.h>

static char ascii[] = {
   0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,
   0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00, [...]
   0x78,0x00,0x79,0x00,0x7a,0x00,0x7b,0x00,0x7c,0x00,
   0x7d,0x00,0x7e,0x00,0x7f,0x00
};
/* if x is not ascii returns pointer to first member (0) */
#define ctos(x) &ascii[((x) & ~0x7f) == 0 ? (x) * 2 : 0]

You should make it clear that this macro may evaluate its
argument more than once, e.g. ALLCAPS.

I'd add a "const" to the declaration of ascii, since you're not
going to change its value.

The desired behavior for characters outside the range 0..127
may vary.  It's easy enough to change this.  For example, you
can handle full 8-bit character values (say, if you're dealing
with Latin-1), by doubling the size of the table and tweaking
the macro definition.

I'd do something more along the lines of isxxxx and toxxxx,
take EOF (expecting -1) or a value in the range of unsigned
char...

#include <stdio.h>

#define B7(M) B6(M,0),B6(M,1)
#define B6(M,p) B5(M,(p)*2+0),B5(M,(p)*2+1)
#define B5(M,p) B4(M,(p)*2+0),B4(M,(p)*2+1)
#define B4(M,p) B3(M,(p)*2+0),B3(M,(p)*2+1)
#define B3(M,p) B2(M,(p)*2+0),B2(M,(p)*2+1)
#define B2(M,p) B1(M,(p)*2+0),B1(M,(p)*2+1)
#define B1(M,p) B0(M,(p)*2+0),B0(M,(p)*2+1)
#define B0(M,p) M(p)

#define AS_STRING(x) { x, 0 }
#define AS_NULL_STRING(x) { 0, 0 }

static const char ascii[][2] =
{ "", B7(AS_STRING), B7(AS_NULL_STRING) };

#define to_asciistr(x) ascii[(x) + 1]

static const char *dummy(int c)
{
return to_asciistr(c);
}

int main(void)
{
int c = 'a';

printf(">%s<\n", to_asciistr(c));
printf(">%s<\n", to_asciistr('b'));
printf(">%s<\n", dummy(c));
printf(">%s<\n", to_asciistr(128));

return 0;
}

Obviously, this assumes CHAR_BIT == 8.
 
D

David RF

David RF escribió:
On 27 ago, 02:35, Peter <ai Nilsson...acay.com.au>escribió:
# definir CTOS (x) y ASCII [((x) & ~ 0x7f) == 0? (x) * 2: 0]
Usted debe dejar claro que esta macro puede evaluar su
argumento más de una vez, por ejemplo, AllCaps.
No entiendo este punto, puede explicar que el argumento Youn
Puede ser evaluado más de una vez?

CTOS (x + +)

& ASCII [((x + +) y ~ 0x7f) == 0? (x + +) * 2: 0]

ops, it seems dangerous, thanks Pete
 
B

Ben Bacarisse

David RF said:
David RF escribió:
On 27 ago, 02:35, Peter <ai Nilsson...acay.com.au>escribió:
# definir CTOS (x) y ASCII [((x) & ~ 0x7f) == 0? (x) * 2: 0]
Usted debe dejar claro que esta macro puede evaluar su
argumento más de una vez, por ejemplo, AllCaps.
No entiendo este punto, puede explicar que el argumento Youn
Puede ser evaluado más de una vez?

CTOS (x + +)

& ASCII [((x + +) y ~ 0x7f) == 0? (x + +) * 2: 0]

It's best to snip sig blocks (even short ones).
ops, it seems dangerous, thanks Pete

Yes. I was surprised to see a macro again because Keith's solution
was prompted by your asking about how to get a string returned from a
function. A function is much safer than a macro and can be as
efficient if it is inlined (you seem to have some C99 features
available to you).
 

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,778
Messages
2,569,605
Members
45,238
Latest member
Top CryptoPodcasts

Latest Threads

Top