473,326 Members | 2,102 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,326 software developers and data experts.

Program to remove C comments (long signature)

This program is long. I don't really want to bore everyone with the
details, but it handles wierd cases like:

/\
* this is a comment *\
/

#define FOO ??/* this is not a comment */

char *a = /* this is a comment "\*/"this is a string"/*" another comment */;

I intend this program to be an example of how to write a kind of state
machine, not really an example of tight coding, but any comments would
be welcome.

Thanks,

-- James
--
/*
* cstripc: A C program to strip comments from C files.
* Usage:
* cstripc [file [...]]
* cstripc [-t]
*
* The '-t' options is used for testing. It prints some pointers to strings
* that are interlaced with comment characters.
*/

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

/*****************/
/**** GLOBALS ****/
/*****************/

static const char *progname;
static int debug_flag;

/**********************/
/**** MAIN PROGRAM ****/
/**********************/

static void print_usage(void);
static void print_test(void);

static FILE * open_input_file(const char *filename);
static void close_input_file(FILE *infile);
static void parse_input_file(FILE *infile);

int
main(int argc, char *argv[])
{
progname = argv[0];
if (progname == 0) {
progname = "cstripc";
}

while (argc > 1) {

if ((*argv[1] != '-') || (strcmp(argv[1], "-") == 0)) {
break;
}

if (strcmp(argv[1], "-t") == 0) {
print_test();
exit(0);
} else if (strcmp(argv[1], "-d") == 0) {
debug_flag = 1;
} else {
fprintf(stderr, "%s: Unrecognized option '%s'\n",
progname, argv[1]);
print_usage();
exit(EXIT_FAILURE);
}

--argc;
++argv;
}

if (argc <= 1) {
parse_input_file(stdin);
exit(0);
}

while (argc > 1) {
FILE *infile;

parse_input_file(infile = open_input_file(argv[1]));
close_input_file(infile);

--argc;
++argv;
}
}

/**************************/
/**** PRINT USAGE/TEST ****/
/**************************/

static const char *usage_string =
"%s: A C program to strip comments from C files.\n"
"Usage:\n"
" %s [file [...]]\n"
" %s [-t]\n"
"\n"
"The '-t' options is used for testing. It prints some pointers to strings\n"
"that are interlaced with comment characters.\n"
;

static void
print_usage(void)
{
fprintf(stderr, usage_string, progname, progname, progname);
}

static const char *a;
static const char *b;
static const char *c;

static void
print_test(void)
{
if (a) puts(a);
if (b) puts(b);
if (c) puts(c);
}

/*******************************/
/**** OPEN/CLOSE INPUT FILE ****/
/*******************************/

static const char *input_file_name;

static FILE *
open_input_file(const char *filename)
{
FILE *infile;

input_file_name = filename;

if (filename == 0) {
return 0;
}

if (strcmp(filename, "-") == 0) {
return stdin;
}

infile = fopen(filename, "r");
if (infile == 0) {
fprintf(stderr, "%s: Could not open '%s' for reading.\n",
progname, filename);
}

return infile;
}

static void
close_input_file(FILE *infile)
{
if (infile) {
if (infile != stdin) {
if (fclose(infile) == EOF)
fprintf(stderr, "%s, Could not close '%s'.\n",
progname, input_file_name);
} else {
clearerr(stdin);
}
}
}

/**************************/
/**** PARSE INPUT FILE ****/
/**************************/

typedef struct scan_state scan_state;
typedef struct scan_context scan_context;

struct scan_context {
scan_state *ss;
char *sbuf;
unsigned sbufsz;
unsigned sbufcnt;
};

struct scan_state {
scan_state *(*scan)(scan_context *ctx, int input);
const char *name;
};

static scan_context initial_scan_context;

static void
parse_input_file(FILE *infile)
{
int c;
scan_context ctx;

if (infile == 0) {
return;
}

ctx = initial_scan_context;

while ((c = fgetc(infile)) != EOF) {
if (debug_flag) {
fprintf(stderr, "%s\n", ctx.ss->name);
}
ctx.ss = ctx.ss->scan(&ctx, c);
}
}

/***********************/
/**** STATE MACHINE ****/
/***********************/

/*
*
************************************************** *************************
* Assume input is a syntactically correct C program.
*
* The basic algorithm is:
* Scan character by character:
* Treat trigraphs as a single character.
* If the sequence does not start a comment, emit the sequence.
* Otherwise,
* Scan character by character:
* Treat trigraphs as a single character.
* Treat the sequence '\\' '\n' as no character.
* If the sequence does not end a comment, continue consuming.
* Otherwise, emit a space, and loop back to top.
************************************************** *************************
*
*/

#define SCAN_STATE_DEFINE(name) \
static scan_state * name##_func(scan_context *ctx, int input); \
static scan_state name##_state = { name##_func, #name }

SCAN_STATE_DEFINE(normal);
SCAN_STATE_DEFINE(normal_maybe_tri_1);
SCAN_STATE_DEFINE(normal_maybe_tri_2);
SCAN_STATE_DEFINE(string);
SCAN_STATE_DEFINE(string_maybe_tri_1);
SCAN_STATE_DEFINE(string_maybe_tri_2);
SCAN_STATE_DEFINE(string_maybe_splice);
SCAN_STATE_DEFINE(char);
SCAN_STATE_DEFINE(char_maybe_tri_1);
SCAN_STATE_DEFINE(char_maybe_tri_2);
SCAN_STATE_DEFINE(char_maybe_splice);
SCAN_STATE_DEFINE(slash);
SCAN_STATE_DEFINE(slash_maybe_tri_1);
SCAN_STATE_DEFINE(slash_maybe_tri_2);
SCAN_STATE_DEFINE(slash_maybe_splice);
SCAN_STATE_DEFINE(slashslash);
SCAN_STATE_DEFINE(slashslash_maybe_tri_1);
SCAN_STATE_DEFINE(slashslash_maybe_tri_2);
SCAN_STATE_DEFINE(slashslash_maybe_splice);
SCAN_STATE_DEFINE(slashsplat);
SCAN_STATE_DEFINE(slashsplat_splat);
SCAN_STATE_DEFINE(slashsplat_splat_maybe_tri_1);
SCAN_STATE_DEFINE(slashsplat_splat_maybe_tri_2);
SCAN_STATE_DEFINE(slashsplat_splat_maybe_splice);

#define SCAN_STATE(name) (&name##_state)

static scan_context initial_scan_context = { SCAN_STATE(normal), 0, 0, 0 };

static void sbuf_append_char(scan_context *ctx, int c);
static void sbuf_append_string(scan_context *ctx, char *s);
static void sbuf_clear(scan_context *ctx);
static void sbuf_emit(scan_context *ctx);

static scan_state *
normal_func(scan_context *ctx, int input)
{
switch (input) {
case '?': sbuf_emit(ctx);
sbuf_append_char(ctx, input);
return SCAN_STATE(normal_maybe_tri_1);
case '"': sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(string);
case '\'': sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(char);
case '/': sbuf_emit(ctx);
sbuf_append_char(ctx, input);
return SCAN_STATE(slash);
default: sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(normal);
}
}

static scan_state *
normal_maybe_tri_1_func(scan_context *ctx, int input)
{
switch (input) {
case '?': sbuf_append_char(ctx, input);
return SCAN_STATE(normal_maybe_tri_2);
default: sbuf_emit(ctx);
return SCAN_STATE(normal)->scan(ctx, input);
}
}

static scan_state *
normal_maybe_tri_2_func(scan_context *ctx, int input)
{
switch (input) {
case '?': putchar(input);
return SCAN_STATE(normal_maybe_tri_2);
case '=':
case '(':
case ')':
case '<':
case '>':
case '!':
case '\'':
case '-':
case '/': sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(normal);
default: sbuf_emit(ctx);
return SCAN_STATE(normal)->scan(ctx, input);
}
}

static scan_state *
string_func(scan_context *ctx, int input)
{
switch (input) {
case '?': sbuf_emit(ctx);
sbuf_append_char(ctx, input);
return SCAN_STATE(string_maybe_tri_1);
case '"': sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(normal);
case '\\': sbuf_emit(ctx);
sbuf_append_char(ctx, input);
return SCAN_STATE(string_maybe_splice);
default: sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(string);
}
}

static scan_state *
string_maybe_tri_1_func(scan_context *ctx, int input)
{
switch (input) {
case '?': sbuf_append_char(ctx, input);
return SCAN_STATE(string_maybe_tri_2);
default: sbuf_emit(ctx);
return SCAN_STATE(string)->scan(ctx, input);
}
}

static scan_state *
string_maybe_tri_2_func(scan_context *ctx, int input)
{
switch (input) {
case '?': putchar(input);
return SCAN_STATE(string_maybe_tri_2);
case '/': sbuf_append_car(ctx, input);
return SCAN_STATE(string_maybe_splice);
case '=':
case '(':
case ')':
case '<':
case '>':
case '!':
case '\'':
case '-': sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(string);
default: sbuf_emit(ctx);
return SCAN_STATE(string)->scan(ctx, input);
}
}

static scan_state *
string_maybe_splice_func(scan_context *ctx, int input)
{
switch (input) {
case '\n':
default: sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(string);
}
}

static scan_state *
char_func(scan_context *ctx, int input)
{
switch (input) {
case '?': sbuf_emit(ctx);
sbuf_append_char(ctx, input);
return SCAN_STATE(char_maybe_tri_1);
case '\'': sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(normal);
case '\\': sbuf_emit(ctx);
sbuf_append_char(ctx, input);
return SCAN_STATE(char_maybe_splice);
default: sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(char);
}
}

static scan_state *
char_maybe_tri_1_func(scan_context *ctx, int input)
{
switch (input) {
case '?': sbuf_append_char(ctx, input);
return SCAN_STATE(char_maybe_tri_2);
default: sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(char)->scan(ctx, input);
}
}

static scan_state *
char_maybe_tri_2_func(scan_context *ctx, int input)
{
switch (input) {
case '?': putchar(input);
return SCAN_STATE(char_maybe_tri_2);
case '/': sbuf_append_char(ctx, input);
return SCAN_STATE(char_maybe_splice);
case '=':
case '(':
case ')':
case '<':
case '>':
case '!':
case '\'':
case '-': sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(char);
default: sbuf_emit(ctx);
return SCAN_STATE(char)->scan(ctx, input);
}
}

static scan_state *
char_maybe_splice_func(scan_context *ctx, int input)
{
switch (input) {
case '\n':
default: sbuf_emit(ctx);
putchar(input);
return SCAN_STATE(char);
}
}

static scan_state *
slash_func(scan_context *ctx, int input)
{
switch (input) {
case '?': sbuf_append_char(ctx, input);
return SCAN_STATE(slash_maybe_tri_1);
case '\\': sbuf_append_char(ctx, input);
return SCAN_STATE(slash_maybe_splice);
case '/': sbuf_clear(ctx);
return SCAN_STATE(slashslash);
case '*': sbuf_clear(ctx);
return SCAN_STATE(slashsplat);
default: sbuf_emit(ctx);
return SCAN_STATE(normal)->scan(ctx, input);
}
}

static scan_state *
slash_maybe_tri_1_func(scan_context *ctx, int input)
{
switch (input) {
case '?': return SCAN_STATE(slash_maybe_tri_2);
default: sbuf_emit(ctx);
return SCAN_STATE(normal)->scan(ctx, input);
}
}

static scan_state *
slash_maybe_tri_2_func(scan_context *ctx, int input)
{
switch (input) {
case '?': sbuf_emit(ctx);
sbuf_append_string(ctx, "??");
return SCAN_STATE(normal_maybe_tri_2);
case '/': sbuf_append_char(ctx, '?');
sbuf_append_char(ctx, input);
return SCAN_STATE(slash_maybe_splice);
case '=':
case '(':
case ')':
case '<':
case '>':
case '!':
case '\'':
case '-': sbuf_append_char(ctx, '?');
sbuf_append_char(ctx, input);
sbuf_emit(ctx);
return SCAN_STATE(normal);
default: sbuf_append_char(ctx, '?');
sbuf_emit(ctx);
return SCAN_STATE(normal)->scan(ctx, input);
}
}

static scan_state *
slash_maybe_splice_func(scan_context *ctx, int input)
{
switch (input) {
case '\n': sbuf_append_char(ctx, input);
return SCAN_STATE(slash);
default: sbuf_emit(ctx);
return SCAN_STATE(normal)->scan(ctx, input);
}
}

static scan_state *
slashslash_func(scan_context *ctx, int input)
{
/* UNUSED */ ctx = ctx;
switch (input) {
case '?': return SCAN_STATE(slashslash_maybe_tri_1);
case '\\': return SCAN_STATE(slashslash_maybe_splice);
case '\n': putchar(' ');
putchar(input);
return SCAN_STATE(normal);
default: return SCAN_STATE(slashslash);
}
}

static scan_state *
slashslash_maybe_tri_1_func(scan_context *ctx, int input)
{
switch (input) {
case '?': return SCAN_STATE(slashslash_maybe_tri_2);
default: return SCAN_STATE(slashslash)->scan(ctx, input);
}
}

static scan_state *
slashslash_maybe_tri_2_func(scan_context *ctx, int input)
{
switch (input) {
case '?': return SCAN_STATE(slashslash_maybe_tri_2);
case '/': return SCAN_STATE(slashslash_maybe_splice);
case '=':
case '(':
case ')':
case '<':
case '>':
case '!':
case '\'':
case '-': return SCAN_STATE(slashslash);
default: return SCAN_STATE(slashslash)->scan(ctx, input);
}
}

static scan_state *
slashslash_maybe_splice_func(scan_context *ctx, int input)
{
switch (input) {
case '\n': return SCAN_STATE(slashslash);
default: return SCAN_STATE(slashslash)->scan(ctx, input);
}
}

static scan_state *
slashsplat_func(scan_context *ctx, int input)
{
/* UNUSED */ ctx = ctx;
switch (input) {
case '*': return SCAN_STATE(slashsplat_splat);
default: return SCAN_STATE(slashsplat);
}
}

static scan_state *
slashsplat_splat_func(scan_context *ctx, int input)
{
switch (input) {
case '?': return SCAN_STATE(slashsplat_splat_maybe_tri_1);
case '\\': return SCAN_STATE(slashsplat_splat_maybe_splice);
case '/': putchar(' ');
return SCAN_STATE(normal);
default: return SCAN_STATE(slashsplat)->scan(ctx, input);
}
}

static scan_state *
slashsplat_splat_maybe_tri_1_func(scan_context *ctx, int input)
{
switch (input) {
case '?': return SCAN_STATE(slashsplat_splat_maybe_tri_2);
default: return SCAN_STATE(slashsplat)->scan(ctx, input);
}
}

static scan_state *
slashsplat_splat_maybe_tri_2_func(scan_context *ctx, int input)
{
switch (input) {
case '/': return SCAN_STATE(slashsplat_splat_maybe_splice);
case '=':
case '(':
case ')':
case '<':
case '>':
case '!':
case '\'':
case '-': return SCAN_STATE(slashsplat);
default: return SCAN_STATE(slashsplat)->scan(ctx, input);
}
}

static scan_state *
slashsplat_splat_maybe_splice_func(scan_context *ctx, int input)
{
switch (input) {
case '\n': return SCAN_STATE(slashsplat_splat);
default: return SCAN_STATE(slashsplat)->scan(ctx, input);
}
}

/*************************/
/**** BUFFER HANDLING ****/
/*************************/

static void
sbuf_append_char(scan_context *ctx, int c)
{
if (ctx->sbuf == 0) {
ctx->sbuf = malloc(ctx->sbufsz = 128);
} else if (ctx->sbufcnt == ctx->sbufsz) {
char *p = realloc(ctx->sbuf, ctx->sbufsz *= 2);
if (p == 0) {
fprintf(stderr, "%s: memory allocation failure\n", progname);
exit(EXIT_FAILURE);
}
ctx->sbuf = p;
}

ctx->sbuf[ctx->sbufcnt++] = c;
ctx->sbuf[ctx->sbufcnt] = '\0';
}

static void
sbuf_append_string(scan_context *ctx, char *s)
{
while (*s != '\0') {
sbuf_append_char(ctx, *s++);
}
}

static void
sbuf_clear(scan_context *ctx)
{
ctx->sbufcnt = 0;
if (ctx->sbuf) {
ctx->sbuf[ctx->sbufcnt] = '\0';
}
}

static void
sbuf_emit(scan_context *ctx)
{
if (ctx->sbuf == 0 || ctx->sbufcnt == 0) {
return;
}

printf("%s", ctx->sbuf);
sbuf_clear(ctx);
}

/********************/
/**** TEST CASES ****/
/********************/

/* a comment */
/\
* a comment split */
/\
\
* a comment split twice */
/*
block comment
*/
/* comment, trailing delimiter split *\
/
/* comment, trailing delimiter split twice *\
\
/
/* comment, trailing delimiter split once, and again by trigraph *\
??/
/

static const char *a = /* comment in code line "*/"Hello, "/**/"World!";
static const char *b = /\
* comment on code line split */ "Hello, " /\
\
* comment on code line split twice */ "World!";

#define FOO ??/* this does not start a comment */

#if defined(__STDC__) && (__STDC__ == 1)
#if defined(__STD_VERSION__) && (__STD_VERSION__ >= 199901L)
//*** MORE TEST CASES ***//
/\
/ // comment split
/\
\
/ // comment split twice
static const char *c = // // comment on code line
"Hello, " /\
/ // comment on code line split
"World!" /\
\
/ // comment on code line split twice.
;

#define BAR ??// this does not start a comment

// This is a // comment \
on two lines

#else
static const char *c = "STDC without STD_VERSION";
#endif
#endif
Nov 13 '05 #1
11 9426
James Hu wrote:
This program is long. I don't really want to bore everyone with the
details, but it handles wierd cases like: ^^^^^
<rant>
Weird how this word is one of the most misspelled words I have ever come
across :) .
</rant>
#define FOO ??/* this is not a comment */


Why is this not a comment? I have always wondered about the behaviour of
comments in "defines". And if it really becomes part of the define, isn't
ommiting it here not the same as ommiting it in all the places where FOO
would be replaced?

Thanks for the info,

--
Martijn
http://www.sereneconcepts.nl
Nov 13 '05 #2
Martijn <su*********************@hotnofiltermail.com> scribbled the following:
James Hu wrote:
This program is long. I don't really want to bore everyone with the
details, but it handles wierd cases like: ^^^^^
<rant>
Weird how this word is one of the most misspelled words I have ever come
across :) .
</rant>

#define FOO ??/* this is not a comment */

Why is this not a comment? I have always wondered about the behaviour of
comments in "defines". And if it really becomes part of the define, isn't
ommiting it here not the same as ommiting it in all the places where FOO
would be replaced?


It's not a comment because the ??/ forms a trigraph, expanding into a \
(backslash).

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"A computer program does what you tell it to do, not what you want it to do."
- Anon
Nov 13 '05 #3
"Martijn" <su*********************@hotNOFILTERmail.com> wrote:
James Hu wrote: <snip>
#define FOO ??/* this is not a comment */


Why is this not a comment? I have always wondered about the behaviour of
comments in "defines".


The problem is not to have a comment after a #define directive, the
"problem" is that ??/ is a trigraph sequence that will be replaced
by a backslash by the C preprocessor /prior/ to comment stripping.
And if it really becomes part of the define, isn't
ommiting it here not the same as ommiting it in all the places where FOO
would be replaced?
Mu. Comments will be replaced by a single blank each, /before/ the
#define directive is handled by the preprocessor. (Otherwise it would
be impossible to 'comment out' preprocessor directives.)

For more info about translation phases I suggest to read section
5.1.1.2 in the C99 Standard.
Thanks for the info,


HTH
Regards
--
Irrwahn
(ir*******@freenet.de)
Nov 13 '05 #4
James Hu <jx*@despammed.com> wrote in message news:<Qc********************@comcast.com>...
This program is long. I don't really want to bore everyone with the
details, but it handles wierd cases like:


That should be "weird".

Found a bug, a cut and paste error. Discovery of the bug and the fix
will be left as an exercise to the interested reader. :-)

-- James
--
Hint: char_maybe_tri_1_func
Nov 13 '05 #5
Martijn wrote:
James Hu wrote:
This program is long. I don't really want to bore everyone with the
details, but it handles wierd cases like:


^^^^^
<rant>
Weird how this word is one of the most misspelled words I have ever come
across :) .
</rant>


Because the rule says I before E, except after C. The rhyme did
acknowledge "weird" and another word as exceptions but I forget that
part of it.
#define FOO ??/* this is not a comment */

Why is this not a comment? I have always wondered about the behaviour of
comments in "defines". And if it really becomes part of the define, isn't
ommiting it here not the same as ommiting it in all the places where FOO
would be replaced?


It's not because it's in a #define. The following is a comment:

#define FOO 123 /* This is a comment */

Sean

Nov 13 '05 #6
Fao, Sean wrote:
Because the rule says I before E, except after C.


$ grep -ci '[^c]ei' /usr/dict/words
764
Nov 13 '05 #7
On 12 Nov 2003 18:53:31 -0800, jx*@despammed.com (James Hu) wrote:
James Hu <jx*@despammed.com> wrote in message news:<Qc********************@comcast.com>...
This program is long. I don't really want to bore everyone with the
details, but it handles wierd cases like:


That should be "weird".

Found a bug, a cut and paste error. Discovery of the bug and the fix
will be left as an exercise to the interested reader. :-)

-- James

Just recently I was reading someone who said that cut and paste should
be disallowed in program editors :-)

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 13 '05 #8
Jeremy Yallop wrote:
Fao, Sean wrote:
Because the rule says I before E, except after C.

$ grep -ci '[^c]ei' /usr/dict/words
764


I hate English :-).

Nov 13 '05 #9
>> <rant>
Weird how this word is one of the most misspelled words I have ever
come across :) .
</rant>


Because the rule says I before E, except after C. The rhyme did
acknowledge "weird" and another word as exceptions but I forget that
part of it.


leisure? (and any derivative?)

Anyway, thanks everybody for the help! I suspected the ??/ was the gotcha
in this comment :) I wasn't even aware of this kind of escape characters...

Thanks!

--
Martijn
http://www.sereneconcepts.nl
Nov 13 '05 #10
On 2003-11-14, Martijn <su*********************@hotNOFILTERmail.com> wrote:
<rant>
Weird how this word is one of the most misspelled words I have ever
come across :) .
</rant>

My spelling is pretty good, but I am no spelling B contender. Perhaps
if I stuck with Latin a few more years in college...
Because the rule says I before E, except after C. The rhyme did
acknowledge "weird" and another word as exceptions but I forget that
part of it.
leisure? (and any derivative?)


Either. Neither. Lein. Heinous. Apparently there are many exceptions.
Anyway, thanks everybody for the help! I suspected the ??/ was the
gotcha in this comment :) I wasn't even aware of this kind of escape
characters...


As others have noted, these are trigraphs. There are also token
sequences that are called digraphs, but they are treated like regular C
tokens, and not globally substituted during the first translation phase
as trigraphs are. My comment stripping program does not give special
treatment to digraphs, because none of the digraph sequences interfere
with a comment.

In an older version of this program (I don't think I ever posted it
here), I converted trigraphs and digraphs to their corresponding "single
character" equivalents. The primary motivation for doing so was that
I wanted to avoid buffering up the scanned input. This meant when
I encountered a line splice after a slash, I would just count how
many line splices occurred until I either did or didn't see a splat.
If eventually a non line splice occurs that is not a splat, then I
would have to output the slash and the number of splices that I had
encountered. The comment program just output the counted number of
line splices using "\\\n", and did not know if a particular splice was
created using a trigraph or not in the original source.

In the version I posted, I decided it was better to output the program
using the original text of the program (modulo turning comments into
a single space character). I suppose if I was really serious about
saving memory, I would buffer up using some sort of RLE compression.

-- James
Nov 13 '05 #11
"Fao, Sean" wrote:
Jeremy Yallop wrote:
Fao, Sean wrote:
Because the rule says I before E, except after C.


$ grep -ci '[^c]ei' /usr/dict/words
764


I hate English :-).


I get 2447. Here are the first few:

abeigh
absenteeism
Acanthodei
acetylenediurein
acetyltropeine
acheilia

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #12

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

Similar topics

8
by: G Patel | last post by:
I wrote the following program to remove C89 type comments from stdin and send it to stdout (as per exercise in K&R2) and it works but I was hoping more experienced programmer would critique the...
4
by: KenFehling | last post by:
Hello. I am wondering if there exists a piece of software that takes multiple .js files that are nicely indented and commented and create one big tightly packed .js file. I'm hoping the one file...
4
by: Rico | last post by:
Hello, I'd like to change a field from an Autonum to a Long data type using DAO. I knwo how to set the attribute, but don't know how to remove it. Any ideas? Thanks!
0
by: Travis Oliphant | last post by:
This post is to gather feedback from the wider community on PEP 357. It is nearing the acceptance stage and has previously been discussed on python-dev. This is a chance for the wider Python...
11
by: srenusa | last post by:
hi, I am quite new to c++ programming and I would need some help with my college assigment: write a program which reads input c++ file and removes commentary. The commentary can be oneline(//) and...
23
by: mike3 | last post by:
Hi. I seem to have made some progress on finding that bug in my program. I deactivated everything in the bignum package that was used except for the returning of BigFloat objects. I even...
3
by: cs | last post by:
Hi, I'm new to C and would appreciate any feedback on the following program, asplit, which splits a file into 2 new files, putting a certain number of lines in the first file, and all the rest...
69
by: raylopez99 | last post by:
They usually don't teach you in most textbooks I've seen that delegates can be used to call class methods from classes that are 'unaware' of the delegate, so long as the class has the same...
9
by: xiao | last post by:
It always dumped when I tried to run it... But it compiles OK. What I want to do is to do a test: Read information from a .dat file and then write it to another file. The original DAT file is...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.