473,397 Members | 1,960 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,397 software developers and data experts.

How to create a Text File Reformater?

Hi, im false beginner in C so that`s why im writting here :).
I have to write a Text Reformater, which should read data from text
file every Verse. In text file may appear special directives (for
example .xx n where n is a variable). Every directive, cause something
else (set marigin, space between verses, lenght of page, header, etc.)

I don't know how to start ? which data structure should I choose ?

Thanks for possible anserws
Nov 14 '05 #1
4 2104
Stuk wrote:

I have to write a Text Reformater, which should read data from text
file every Verse. In text file may appear special directives (for
example .xx n where n is a variable). Every directive, cause something
else (set marigin, space between verses, lenght of page, header, etc.)

I don't know how to start ? which data structure should I choose ?


Start by reading a file and writing a file, using input and output
buffers. When you have that working you can complicate the
transfer between buffers. Think about how big the buffers should
be, and what they should hold. Make sure you organize it so you
can change your mind without great pain.

The following elementary filter may give you some ideas:

/* ----- justify.c -----
Filter text file, right justifying by inserting
spaces between words. Words are anything separated
by blanks, tabs, newlines, formfeeds, bell, etc.

The single (optional) parameter is the output line
length, and defaults to 65. Execution without any
input redirections causes a help message.

This is a quick and dirty utility.
Released to public domain by:
<mailto:cb********@worldnet.att.net>
*/

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

#define RHDEFAULT 65
#define RHMIN 20

static int rhcol; /* right hand column limit */
static int ragged; /* No rh justification, 0 init */

/* ------------------- */

/* This is very likely to be non-portable */
/* DOES NOT check fp open for reading */
/* NULL fp is considered a keyboard here! */
static int akeyboard(FILE *fp)
{
#ifndef __TURBOC__
# ifdef __STDC__
/* This dirty operation allows gcc -ansi -pedantic */
extern int fileno(FILE *fp);
extern int isatty(int fn);
# endif
#endif
return ((fp != NULL) && isatty(fileno(fp)));
} /* akeyboard */

/* ------------------- */

static void help(char *phrase1, char *phrase2)
{
if (phrase1) fprintf(stderr, "%s", phrase1);
if (phrase2) fprintf(stderr, "%s", phrase2);
fprintf(stderr, "\n"
"Usage: justify [rightmargin] <infile >outfile\n"
" The default rightmargin is 65\n"
" and values less than 20 are rejected\n"
"\n"
"A large value of rightmargin will effectively\n"
"convert all paragraphs into single lines\n"
"\n"
"A negative rightmargin causes ragged right\n"
"\n"
"A blank line delimits paragraphs\n");
} /* help */

/* ------------------- */

static int initialize(int argc, char *argv[])
{
long rightcol;
char *err;

if (akeyboard(stdin) || (argc > 2)) {
help(NULL, NULL);
return 0;
}
rhcol = RHDEFAULT;
if (2 == argc) {
rightcol = strtol(argv[1], &err, 10);
if (rightcol < 0) {
rightcol = -rightcol;
ragged = 1;
}
if ((err == argv[1]) || (rightcol < RHMIN)) {
help("Bad argument: ", argv[1]);
return 0;
}
else rhcol = rightcol;
}
return 1;
} /* initialize */

/* ------------------- */

static void cleanup(void)
{
} /* cleanup */

/* ------------------- */

/* ================================== */
/* Routines for text input and output */
/* ================================== */

static void skipblanks(FILE *f)
{
int ch;

while ( (' ' == (ch = getc(f))) || ('\t' == ch) ||
('\v' == ch) || ('\f' == ch) || ('\a' == ch) )
continue;
ungetc(ch, f);
} /* skipblanks */

/* ------------------- */

/* The file is assumed to hold no control chars */
/* other than \n \t \v \a and \f. A blank line */
/* marks a paragraph ending word */
static int nextword(FILE *f, char *buffer, int max)
{
int i, ch;

skipblanks(f);
if (EOF == (ch = getc(f))) return 0;

/* Detect paragraph endings as \n\n */
if ('\n' == ch) {
skipblanks(f); ch = getc(f);
if ('\n' == ch) { /* paragraph ending */
buffer[0] = buffer[1] = ch; /* wd = "\n\n" */
buffer[2] = '\0';
/* now we have to absorb any more blank lines */
do {
skipblanks(f); ch = getc(f);
} while ('\n' == ch);
ungetc(ch, f);
return 1;
}
}
/* now ch holds the first non-blank. Use all printable */
if (EOF == ch) return 0;
if (!isgraph(ch)) {
fprintf(stderr, "'%c', 0x%x WARN: Invalid character\n",
ch, (unsigned)ch);
}

i = 0;
do {
buffer[i++] = ch;
if (i >= max) { /* truncate over long words */
i--;
break; /* leaving ch for next word */
}
ch = getc(f);
} while (isgraph(ch));

ungetc(ch, f); /* save for next word, may be \n */
buffer[i] = '\0'; /* terminate string */
return 1;
} /* nextword */

/* ------------------- */

static void justify(char *ln, int wdgaps, int xtra, FILE *out)
{
int insert, i;
static int oddln = 0; /* for rt left blank insertion */
char ch;

#ifdef DEBUG
fprintf(out, "%2d %2d ", wdgaps, xtra);
#endif
insert = 0; oddln = !oddln;
if (wdgaps)
while (xtra > wdgaps) {
insert++; xtra -= wdgaps;
}
while ((ch = *ln++)) {
putc(ch, out);
if (' ' == ch) {
if (xtra) {
xtra--;
putc(' ', out);
}
for (i = insert; i; i--) putc(' ', out);
}
}
putc('\n', out);
} /* justify */

/* ------------------- */

static int filter(FILE *in, FILE *out)
{
char *buf;
char *ln;
int wdcount, lnlgh, wdlgh;
char *eop = "\n\n"; /* end of paragraph */
int done, endpar;

if (!(buf = malloc(rhcol+1))) exit(EXIT_FAILURE);
if (!(ln = malloc(rhcol+1))) exit(EXIT_FAILURE);

done = !nextword(in, buf, rhcol + 1);
endpar = !strcmp(buf, eop);

while (!endpar && !done) {
/* form paragraph */
wdlgh = strlen(buf);
wdcount = 0;
*ln = '\0'; lnlgh = 0;

while ((((lnlgh + wdlgh) < rhcol) || !lnlgh)
&& !done && !endpar) {
/* form a line */
if (lnlgh) ln[lnlgh++] = ' ';
strcpy(ln + lnlgh, buf);
lnlgh += wdlgh;
wdcount++;

done = !nextword(in, buf, rhcol + 1);
endpar = !strcmp(buf, eop);
wdlgh = strlen(buf);
}

/* dump the line, wdcount words */
if (endpar || done) lnlgh = rhcol;
if (ragged) fprintf(out, "%s\n", ln);
else justify(ln, wdcount-1, rhcol-lnlgh, out);

if (endpar) {
fputc('\n', out);
done = !nextword(in, buf, rhcol + 1);
endpar = !strcmp(buf, eop);
}
}
return 0;
} /* filter */

/* ------------------- */

int main(int argc, char *argv[])
{
if (!initialize(argc, argv)) return EXIT_FAILURE;
else {
(void)filter(stdin, stdout);
cleanup();
}
return 0;
} /* main */

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #2
Stuk wrote:
Hi, im false beginner in C so that`s why im writting here :).
I have to write a Text Reformater, which should read data from text
file every Verse. In text file may appear special directives (for
example .xx n where n is a variable). Every directive, cause something
else (set marigin, space between verses, lenght of page, header, etc.)

I don't know how to start ? which data structure should I choose ?

Thanks for possible anserws


CBFalconer already gave you some good advice.
Here's another piece.

Get structure into your problem:
E.g. if your special directives governing the general look of the output
are at the very beginning of the input, you may consider partitioning
the problem into
- get the format info
- act upon it with the rest of the text
You could store the format info in a structure which then gets passed
to the text output routine.

There is often more than one way to look at something:
If there are, for example, markup directives which change the look of
parts of the processed text, you could either treat the output of this
text part in a special way or you could generate from this text part
text which can be output in the normal way but has undergone some
transformations.
The latter way has the advantage that you still have only one output
routine but it could have the disadvantage that it is very inefficient.

Look for possible extensions:
If there is something which also could be in the scope of your
program from a logical point of view, do not make it impossible to
extend your program into this direction without effectively rewriting
it.

There is much more, but this may get you started.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #3
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

CBFalconer wrote:
Stuk wrote:
I have to write a Text Reformater, which should read data from text
file every Verse. In text file may appear special directives (for
example .xx n where n is a variable). Every directive, cause something
else (set marigin, space between verses, lenght of page, header, etc.)

I don't know how to start ? which data structure should I choose ?

Start by reading a file and writing a file, using input and output
buffers. When you have that working you can complicate the
transfer between buffers. Think about how big the buffers should
be, and what they should hold. Make sure you organize it so you
can change your mind without great pain.

[snip]

To that sage advice I will add...

Stuk: Get yourself a copy of "Software Tools" by Brian W. Kernighan & P.J.
Plauger (Addison-Wesley Publishing Company, ISBN 0-201-03669-X)

In that book, you will find a multitude of excellent advice on developing a
program, along with an example of a "Text Reformatter". Of course, the text
reformatter is written in RatFor (a C-like dialect of Fortran), so you won't
be able to crib the source code directly, but from the text and example code
you should be able to create your own formatter in C without any problem.
- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFCBuBqagVFX4UWr64RAn04AJ9pUwC8YHTgaMtlyCZVWX/cC6WxGQCgpFx2
AUEkfRklvg8rKK9qr6TZkyE=
=RMbE
-----END PGP SIGNATURE-----
Nov 14 '05 #4
Thanks so lot for CBFalconer and Lew Pitcher for advices :)
Stuk: Get yourself a copy of "Software Tools" by Brian W. Kernighan & P.J.
Plauger (Addison-Wesley Publishing Company, ISBN 0-201-03669-X)
In that book, you will find a multitude of excellent advice on developing a
program, along with an example of a "Text Reformatter". Of course, the text
reformatter is written in RatFor (a C-like dialect of Fortran), so you won't
be able to crib the source code directly, but from the text and example code
you should be able to create your own formatter in C without any problem.


Yeah I know but I came up against some problems during searching this
book. Its unavailable in my region, where im live. I think this prog,
which i have to make, is like as two peas similar.
Nov 14 '05 #5

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

Similar topics

9
by: Lauren Quantrell | last post by:
Is there a way to create a text file (such as a Windows Notepad file) by using a trigger on a table? What I want to do is to send a row of information to a table where the table: tblFileData has...
7
by: dog | last post by:
I've seen plenty of articles on this topic but none of them have been able to solve my problem. I am working with an Access 97 database on an NT4.0 machine, which has many Access reports. I...
1
by: Andrew Chanter | last post by:
I am writing a little routine to perform the following operations from an Acces 97 mdb: 1. create a fixed width text file 2. create/establish a table type link to the text file in Access 3....
6
by: Chad Crowder | last post by:
Getting the following error on my production server whether the file exists or not: "System.IO.IOException: Cannot create a file when that file already exists." Here's the code generating the...
6
by: windandwaves | last post by:
Hi Folk Some of my clients asked me to create "fancy emails" for them (aka html formatted emails). I know how to make a nice html document, but I had trouble creating a simple way to provide...
0
by: CSharpguy | last post by:
I have a web form that has 22 text boxes on it were the user can enter in data, then click a button that needs to create a text file. I can create the text file fine, but how can I create a text...
8
by: barb | last post by:
So that the world at large benefits from our efforts, here is one fully documented way to use Windows Irfanview freeware to create thumbnail web galleries (http://www.irfanview.com). STEP 1:...
8
by: Vincent Delporte | last post by:
Hello When I copy/paste Python code from the web, every so often, the TABs are wrong, which means that the code won't work and I have to manually reformat the code. Is there a code reformater...
15
by: lxyone | last post by:
Using a flat file containing table names, fields, values whats the best way of creating html pages? I want control over the html pages ie 1. layout 2. what data to show 3. what controls to...
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
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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
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,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...

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.