By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,045 Members | 1,305 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,045 IT Pros & Developers. It's quick & easy.

Write to file

P: n/a
Hello,

I'm trying to output buffer content to a file. I either get an access
violation error, or crazy looking output in the file depending on
which method I use to write the file. Can anyone help out a newbie?
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define DISPLAY 117 /* Length of display line */
#define PAGE_LENGTH 20 /* Lines per page */

int main(int argc, char *argv[])
{
FILE *pfile;
FILE *outfile;
char *p;

unsigned char buffer[DISPLAY/4 - 1]; /* File input buffer */
int count = 0; /* Count of characters in buffer */
int lines = 0; /* Number of lines displayed */
int i = 0; /* Loop counter */

char string [100];
pfile = fopen ("my.txt" , "r");

while(!feof(pfile)) /* Continue until end of file */
{
if(count < sizeof buffer) /* If the buffer is not full */
/* Read a character */
buffer[count++] = (unsigned char)fgetc(pfile);
else
{
/* Now display buffer contents as characters */
for(count = 0; count < sizeof buffer; count++)
printf("%c", isprint(buffer[count]) ? buffer[count]:'.');
printf("\n"); /* End the line */
count = 0; /* Reset count */

if(!(++lines%PAGE_LENGTH)) /* End of page? */
if(getchar()=='E') /* Wait for Enter */
return 0; /* E pressed */
}
}

/* Display last line as characters */
for(i = 0; i < count; i++)
{
printf("%c",isprint(buffer[i]) ? buffer[i]:'.');
}

printf("\n");
fclose(pfile); /* Close the file */

//re-open file and write out the buffer contents
outfile = fopen ("myOutput.txt" , "w");

if(outfile==NULL)
{
return 0;
}

//causes an access violation error
for(count = 0; count < sizeof buffer; count++)
{
fputc(outfile, isprint(buffer[count]) ? buffer[count]:'.');
}

//causes crazy output in file
/*for(count = 0; count < sizeof buffer; count++)
{
(int) fwrite(buffer, 1, isprint(buffer[count]), outfile);
}*/

fclose(outfile);
getchar();
return 0;
}

Jun 13 '07 #1
Share this Question
Share on Google+
24 Replies


P: n/a
Bill <bi*********@allstate.comwrites:
Hello,

I'm trying to output buffer content to a file. I either get an access
violation error, or crazy looking output in the file depending on
which method I use to write the file. Can anyone help out a newbie?
Sure...
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define DISPLAY 117 /* Length of display line */
#define PAGE_LENGTH 20 /* Lines per page */

int main(int argc, char *argv[])
{
FILE *pfile;
FILE *outfile;
char *p;

unsigned char buffer[DISPLAY/4 - 1]; /* File input buffer */
int count = 0; /* Count of characters in buffer */
int lines = 0; /* Number of lines displayed */
int i = 0; /* Loop counter */

char string [100];
pfile = fopen ("my.txt" , "r");
You should check it worked. I know you know this!
while(!feof(pfile)) /* Continue until end of file */
This will cause you some surprises and won't do what you think. You
should check the return from the read operation (in you case) fgetc:

int c;
....
while ((c = fgetc(pfile)) != EOF) {
...

The feof function only returns a non-zero value *after* an input
operation has failed due to and end-of-file condition. It should be
used only to tell *why* things have gone wrong.
{
if(count < sizeof buffer) /* If the buffer is not full */
/* Read a character */
buffer[count++] = (unsigned char)fgetc(pfile);
else
{
/* Now display buffer contents as characters */
for(count = 0; count < sizeof buffer; count++)
printf("%c", isprint(buffer[count]) ? buffer[count]:'.');
printf("\n"); /* End the line */
count = 0; /* Reset count */

if(!(++lines%PAGE_LENGTH)) /* End of page? */
if(getchar()=='E') /* Wait for Enter */
return 0; /* E pressed */
There getchar calls will normally be working on a buffered input so it
is not a good way to "pause" your program. If I wanted to do this (and
for some reason I don't these days) I'd write a function to read a
whole line of input and decide what to do based on that.
}
}

/* Display last line as characters */
for(i = 0; i < count; i++)
{
printf("%c",isprint(buffer[i]) ? buffer[i]:'.');
}

printf("\n");
fclose(pfile); /* Close the file */
You should check if this worked also.
//re-open file and write out the buffer contents
outfile = fopen ("myOutput.txt" , "w");

if(outfile==NULL)
{
return 0;
}

//causes an access violation error
for(count = 0; count < sizeof buffer; count++)
{
fputc(outfile, isprint(buffer[count]) ? buffer[count]:'.');
You should check that this worked. Get in the habit of checking
everything that there is to check!
}

//causes crazy output in file
/*for(count = 0; count < sizeof buffer; count++)
{
(int) fwrite(buffer, 1, isprint(buffer[count]), outfile);
}*/
This will repeatedly try to print the first character in buffer as
many times as there are printable characters in the buffer!. Also, by
using it this way (asking to write no data sometimes) you make error
checking much harder. Stick with the fputc method. It is fine. For
the record you probably intended:

fwrite(&buffer[count], 1, isprint(buffer[count]), outfile);

If you want to print a whole buffer. Process it first:

for (count = 0; count < sizeof buffer; count++)
if (!isprint(buffer[count]))
buffer[count] = '.';

if (fwrite(buffer, 1, count, outfile) != count)
/* report a write error... */
>
fclose(outfile);
getchar();
return 0;
}
--
Ben.
Jun 13 '07 #2

P: n/a
On Jun 13, 6:09 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
Bill <bill.war...@allstate.comwrites:
Hello,
I'm trying to output buffer content to a file. I either get an access
violation error, or crazy looking output in the file depending on
which method I use to write the file. Can anyone help out a newbie?

Sure...


#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define DISPLAY 117 /* Length of display line */
#define PAGE_LENGTH 20 /* Lines per page */
int main(int argc, char *argv[])
{
FILE *pfile;
FILE *outfile;
char *p;
unsigned char buffer[DISPLAY/4 - 1]; /* File input buffer */
int count = 0; /* Count of characters in buffer */
int lines = 0; /* Number of lines displayed */
int i = 0; /* Loop counter */
char string [100];
pfile = fopen ("my.txt" , "r");

You should check it worked. I know you know this!
while(!feof(pfile)) /* Continue until end of file */

This will cause you some surprises and won't do what you think. You
should check the return from the read operation (in you case) fgetc:

int c;
....
while ((c = fgetc(pfile)) != EOF) {
...

The feof function only returns a non-zero value *after* an input
operation has failed due to and end-of-file condition. It should be
used only to tell *why* things have gone wrong.
{
if(count < sizeof buffer) /* If the buffer is not full */
/* Read a character */
buffer[count++] = (unsigned char)fgetc(pfile);
else
{
/* Now display buffer contents as characters */
for(count = 0; count < sizeof buffer; count++)
printf("%c", isprint(buffer[count]) ? buffer[count]:'.');
printf("\n"); /* End the line */
count = 0; /* Reset count */
if(!(++lines%PAGE_LENGTH)) /* End of page? */
if(getchar()=='E') /* Wait for Enter */
return 0; /* E pressed */

There getchar calls will normally be working on a buffered input so it
is not a good way to "pause" your program. If I wanted to do this (and
for some reason I don't these days) I'd write a function to read a
whole line of input and decide what to do based on that.
}
}
/* Display last line as characters */
for(i = 0; i < count; i++)
{
printf("%c",isprint(buffer[i]) ? buffer[i]:'.');
}
printf("\n");
fclose(pfile); /* Close the file */

You should check if this worked also.
//re-open file and write out the buffer contents
outfile = fopen ("myOutput.txt" , "w");
if(outfile==NULL)
{
return 0;
}
//causes an access violation error
for(count = 0; count < sizeof buffer; count++)
{
fputc(outfile, isprint(buffer[count]) ? buffer[count]:'.');

You should check that this worked. Get in the habit of checking
everything that there is to check!
}
//causes crazy output in file
/*for(count = 0; count < sizeof buffer; count++)
{
(int) fwrite(buffer, 1, isprint(buffer[count]), outfile);
}*/

This will repeatedly try to print the first character in buffer as
many times as there are printable characters in the buffer!. Also, by
using it this way (asking to write no data sometimes) you make error
checking much harder. Stick with the fputc method. It is fine. For
the record you probably intended:

fwrite(&buffer[count], 1, isprint(buffer[count]), outfile);

If you want to print a whole buffer. Process it first:

for (count = 0; count < sizeof buffer; count++)
if (!isprint(buffer[count]))
buffer[count] = '.';

if (fwrite(buffer, 1, count, outfile) != count)
/* report a write error... */
fclose(outfile);
getchar();
return 0;
}

--
Ben.- Hide quoted text -

- Show quoted text -
Thanks alot. I'm making progress. No errors now, but the output in
the file is screwy. The code:
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define DISPLAY 117 /* Length of display line */
#define PAGE_LENGTH 20 /* Lines per page */

int main(int argc, char *argv[])
{
FILE *pfile; /* File pointer */
FILE *outfile;
char *p;
int c;

unsigned char buffer[DISPLAY/4 - 1]; /* File input buffer */
int count = 0; /* Count of characters in buffer */
int lines = 0; /* Number of lines displayed */
int i = 0; /* Loop counter */

char string [100];
pfile = fopen ("my.txt" , "r");
while((c = fgetc(pfile)) != EOF) /* Continue until end of
file */
{
if(count < sizeof buffer) /* If the buffer is not full */
/* Read a character */
buffer[count++] = (unsigned char)fgetc(pfile);
else
{
/* Now display buffer contents as characters */
for(count = 0; count < sizeof buffer; count++)
printf("%c", isprint(buffer[count]) ? buffer[count]:'.');
printf("\n"); /* End the line */
count = 0; /* Reset count */

if(!(++lines%PAGE_LENGTH)) /* End of page? */
if(getchar()=='E') /* Wait for Enter */
return 0; /* E pressed */
}
}

/* Display last line as characters */
for(i = 0; i < count; i++)
{
printf("%c",isprint(buffer[i]) ? buffer[i]:'.');
}

printf("\n");
fclose(pfile); /* Close the file */

//re-open file and write out the buffer contents
outfile = fopen ("myOutput.txt" , "w");

if(outfile==NULL)
{
return 0;
}
for(count = 0; count < sizeof buffer; count++)
{
if(!isprint(buffer[count]))
{
buffer[count] = '.';
}
else
{
fputc(buffer[count],outfile);
}
//fputc(outfile, isprint(buffer[count]) ? buffer[count]:'.');
}

/*for(count = 0; count < sizeof buffer; count++)
{
(int) fwrite(buffer, 1, isprint(buffer[count]), outfile);
}*/

fclose(outfile);
getchar();
return 0;
}

Input file contents:
Fred Flinstone 123-456-7890
Barney Rubble 123-789-4561

Output file:
B12y7p456r

Jun 13 '07 #3

P: n/a
Bill <bi*********@allstate.comwrites:
Thanks alot. I'm making progress. No errors now, but the output in
the file is screwy. The code:
Please trip your replies (and always trim signature lines).
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define DISPLAY 117 /* Length of display line */
#define PAGE_LENGTH 20 /* Lines per page */

int main(int argc, char *argv[])
{
FILE *pfile; /* File pointer */
FILE *outfile;
char *p;
int c;

unsigned char buffer[DISPLAY/4 - 1]; /* File input buffer */
int count = 0; /* Count of characters in buffer */
int lines = 0; /* Number of lines displayed */
int i = 0; /* Loop counter */

char string [100];
pfile = fopen ("my.txt" , "r");
while((c = fgetc(pfile)) != EOF) /* Continue until end of
file */
{
if(count < sizeof buffer) /* If the buffer is not full */
/* Read a character */
buffer[count++] = (unsigned char)fgetc(pfile);
I intended you you use c here not read another character!
else
{
/* Now display buffer contents as characters */
for(count = 0; count < sizeof buffer; count++)
printf("%c", isprint(buffer[count]) ? buffer[count]:'.');
printf("\n"); /* End the line */
count = 0; /* Reset count */
Your input is long enough to trigger this condition. You reuse the buffer.
if(!(++lines%PAGE_LENGTH)) /* End of page? */
if(getchar()=='E') /* Wait for Enter */
return 0; /* E pressed */
}
}

/* Display last line as characters */
for(i = 0; i < count; i++)
{
printf("%c",isprint(buffer[i]) ? buffer[i]:'.');
}

printf("\n");
fclose(pfile); /* Close the file */

//re-open file and write out the buffer contents
outfile = fopen ("myOutput.txt" , "w");

if(outfile==NULL)
{
return 0;
}
for(count = 0; count < sizeof buffer; count++)
{
if(!isprint(buffer[count]))
{
buffer[count] = '.';
}
else
{
fputc(buffer[count],outfile);
}
You took a suggestion to modify the buffer and combined it with single
character printing to produce something rather odd. It is not wrong,
just odd. Why change buffer[count] when is it not a printing
character if you don't then print it?
//fputc(outfile, isprint(buffer[count]) ? buffer[count]:'.');
}

/*for(count = 0; count < sizeof buffer; count++)
{
(int) fwrite(buffer, 1, isprint(buffer[count]), outfile);
}*/

fclose(outfile);
getchar();
return 0;
}

Input file contents:
Fred Flinstone 123-456-7890
Barney Rubble 123-789-4561

Output file:
B12y7p456r
Not what I get, but still.

I should point out that although I have only commented on details, the
overall design of this program looks a bit wacky. If you intend to
process text files, why do you have a buffer of size 117/4-1? Why are
you happy to simply reuse the space when you read more than these 28
characters? If the input has 30 characters, your buffer will contain
numbers 29 and 30 followed by character numbers 3, 4 and so on. It
all looks very odd.

You should maybe say what you are actually trying to do.

--
Ben.
Jun 13 '07 #4

P: n/a
On Jun 13, 7:40 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
Bill <bill.war...@allstate.comwrites:
Thanks alot. I'm making progress. No errors now, but the output in
the file is screwy. The code:

Please trip your replies (and always trim signature lines).


#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define DISPLAY 117 /* Length of display line */
#define PAGE_LENGTH 20 /* Lines per page */
int main(int argc, char *argv[])
{
FILE *pfile; /* File pointer */
FILE *outfile;
char *p;
int c;
unsigned char buffer[DISPLAY/4 - 1]; /* File input buffer */
int count = 0; /* Count of characters in buffer */
int lines = 0; /* Number of lines displayed */
int i = 0; /* Loop counter */
char string [100];
pfile = fopen ("my.txt" , "r");
while((c = fgetc(pfile)) != EOF) /* Continue until end of
file */
{
if(count < sizeof buffer) /* If the buffer is not full */
/* Read a character */
buffer[count++] = (unsigned char)fgetc(pfile);

I intended you you use c here not read another character!
else
{
/* Now display buffer contents as characters */
for(count = 0; count < sizeof buffer; count++)
printf("%c", isprint(buffer[count]) ? buffer[count]:'.');
printf("\n"); /* End the line */
count = 0; /* Reset count */

Your input is long enough to trigger this condition. You reuse the buffer.


if(!(++lines%PAGE_LENGTH)) /* End of page? */
if(getchar()=='E') /* Wait for Enter */
return 0; /* E pressed */
}
}
/* Display last line as characters */
for(i = 0; i < count; i++)
{
printf("%c",isprint(buffer[i]) ? buffer[i]:'.');
}
printf("\n");
fclose(pfile); /* Close the file */
//re-open file and write out the buffer contents
outfile = fopen ("myOutput.txt" , "w");
if(outfile==NULL)
{
return 0;
}
for(count = 0; count < sizeof buffer; count++)
{
if(!isprint(buffer[count]))
{
buffer[count] = '.';
}
else
{
fputc(buffer[count],outfile);
}

You took a suggestion to modify the buffer and combined it with single
character printing to produce something rather odd. It is not wrong,
just odd. Why change buffer[count] when is it not a printing
character if you don't then print it?


//fputc(outfile, isprint(buffer[count]) ? buffer[count]:'.');
}
/*for(count = 0; count < sizeof buffer; count++)
{
(int) fwrite(buffer, 1, isprint(buffer[count]), outfile);
}*/
fclose(outfile);
getchar();
return 0;
}
Input file contents:
Fred Flinstone 123-456-7890
Barney Rubble 123-789-4561
Output file:
B12y7p456r

Not what I get, but still.

I should point out that although I have only commented on details, the
overall design of this program looks a bit wacky. If you intend to
process text files, why do you have a buffer of size 117/4-1? Why are
you happy to simply reuse the space when you read more than these 28
characters? If the input has 30 characters, your buffer will contain
numbers 29 and 30 followed by character numbers 3, 4 and so on. It
all looks very odd.

You should maybe say what you are actually trying to do.

--
Ben.- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -
Yes. It has become wacky. What I'm trying to do is read the contents
of a file into a buffer, find a particular string in the buffer, make
an edit in the found string and write the same file back out.

Jun 13 '07 #5

P: n/a
Bill <bi*********@allstate.comwrites:
On Jun 13, 7:40 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
>You should maybe say what you are actually trying to do.

Yes. It has become wacky. What I'm trying to do is read the contents
of a file into a buffer, find a particular string in the buffer, make
an edit in the found string and write the same file back out.
Ah, well... that could be done much more simply. Presumably this is some
class assignment or you would simply use one of the many fine tools
that can do this?

You did not take my advice to trim your replies (you quoted everything
including my signature block). That will have won you no favours from
others here and it discourages me from helping further.

--
Ben.
Jun 13 '07 #6

P: n/a
>
You did not take my advice to trim your replies (you quoted everything
including my signature block). That will have won you no favours from
others here and it discourages me from helping further.
Sorry. Yes it is an assignment, but I'm trying to take it further
than what was assigned.
I really wish to learn the language.
Jun 13 '07 #7

P: n/a
On 13 Jun, 13:04, Bill <bill.war...@allstate.comwrote:
>
Thanks alot. I'm making progress. No errors now, but the output in
the file is screwy. The code:

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

#define DISPLAY 117 /* Length of display line */
#define PAGE_LENGTH 20 /* Lines per page */

int main(int argc, char *argv[])
{
FILE *pfile; /* File pointer */
FILE *outfile;
char *p;
int c;

unsigned char buffer[DISPLAY/4 - 1]; /* File input buffer */
Initialising this would be advisable, given what you're going to do
with it later.
int count = 0; /* Count of characters in buffer */
int lines = 0; /* Number of lines displayed */
int i = 0; /* Loop counter */

char string [100];
pfile = fopen ("my.txt" , "r");

while((c = fgetc(pfile)) != EOF) /* Continue until end of
file */
{
if(count < sizeof buffer) /* If the buffer is not full */
/* Read a character */
buffer[count++] = (unsigned char)fgetc(pfile);
This needs to be changed to :
buffer[count++] = (unsigned char)c;

As otherwise you are reading the first character in the while loop and
then ignoring it and reading a second character here. This is why you
get every other character in the output.

else
{
/* Now display buffer contents as characters */
for(count = 0; count < sizeof buffer; count++)
printf("%c", isprint(buffer[count]) ? buffer[count]:'.');
printf("\n"); /* End the line */
count = 0; /* Reset count */
This is what's causing your output file to look a bit odd. Once you've
read the input up to a full buffer, you just print it to screen and
then re-start at the beginning of the buffer. This data never (except
for the last couple of rows, by chance) goes to the datafile and so
you don't get everything that you're after. So you either need to
output it here or store it somehow.
>
if(!(++lines%PAGE_LENGTH)) /* End of page? */
if(getchar()=='E') /* Wait for Enter */
return 0; /* E pressed */
}
}

/* Display last line as characters */
for(i = 0; i < count; i++)
{
printf("%c",isprint(buffer[i]) ? buffer[i]:'.');
}

printf("\n");
fclose(pfile); /* Close the file */

//re-open file and write out the buffer contents
outfile = fopen ("myOutput.txt" , "w");

if(outfile==NULL)
{
return 0;
}

for(count = 0; count < sizeof buffer; count++)
You also don't know that all of buffer has been filled. It's not
initialised so it could well be causing undefince behaviour here. You
either need to keep a count of how many characters you've read or need
to initialise the array and/or populate and look for '\0' characters
at read time.

Given what you're trying to do I would suggest you take a look at the
fgets function.
{
if(!isprint(buffer[count]))
{
buffer[count] = '.';
}
else
{
fputc(buffer[count],outfile);
}

And this lot doesn't need to be in an else, it needs to happen every
time.

<snip rest of code>
Jun 13 '07 #8

P: n/a
Bill <bi*********@allstate.comwrites:
>>
You did not take my advice to trim your replies (you quoted everything
including my signature block). That will have won you no favours from
others here and it discourages me from helping further.

Sorry.
Well you get much credit for *not* digging in and arguing that your
way of posting is the right way. Thank you.
Yes it is an assignment, but I'm trying to take it further
than what was assigned.
I really wish to learn the language.
A simple solution, which will concentrate on the language features
rather than on getting the searching algorithm right, is to:

(1) Find out how big the file is. There are two ways to do this in
standard C, but only one that is guaranteed to work. If I were your
tutor I would accept both, provided your program reports any failures
as such.

(2) Allocate space for the whole file and read it in.

(3) Search for the string to replace whilst writing out those parts
that are not to be replaced.

There are obvious limitations with this strategy, but it will help you
learn. A fully general search and replace program is quite complex
for a beginner.

--
Ben.
Jun 13 '07 #9

P: n/a
There are obvious limitations with this strategy, but it will help you
learn. A fully general search and replace program is quite complex
for a beginner.

--
Ben.
Thanks for the tips.

Jun 13 '07 #10

P: n/a
On 6 13 , 6 28 , Bill <bill.war...@allstate.comwrote:
Hello,

I'm trying to output buffer content to a file. I either get an access
violation error, or crazy looking output in the file depending on
which method I use to write the file. Can anyone help out a newbie?

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

#define DISPLAY 117 /* Length of display line */
#define PAGE_LENGTH 20 /* Lines per page */

int main(int argc, char *argv[])
{
FILE *pfile;
FILE *outfile;
char *p;

unsigned char buffer[DISPLAY/4 - 1]; /* File input buffer */
int count = 0; /* Count of characters in buffer */
int lines = 0; /* Number of lines displayed */
int i = 0; /* Loop counter */

char string [100];
pfile = fopen ("my.txt" , "r");

while(!feof(pfile)) /* Continue until end of file */
{
if(count < sizeof buffer) /* If the buffer is not full */
/* Read a character */
buffer[count++] = (unsigned char)fgetc(pfile);
else
{
/* Now display buffer contents as characters */
for(count = 0; count < sizeof buffer; count++)
printf("%c", isprint(buffer[count]) ? buffer[count]:'.');
printf("\n"); /* End the line */
count = 0; /* Reset count */

if(!(++lines%PAGE_LENGTH)) /* End of page? */
if(getchar()=='E') /* Wait for Enter */
return 0; /* E pressed */
}
}

/* Display last line as characters */
for(i = 0; i < count; i++)
{
printf("%c",isprint(buffer[i]) ? buffer[i]:'.');
}

printf("\n");
fclose(pfile); /* Close the file */

//re-open file and write out the buffer contents
outfile = fopen ("myOutput.txt" , "w");

if(outfile==NULL)
{
return 0;
}

//causes an access violation error
for(count = 0; count < sizeof buffer; count++)
{
fputc(outfile, isprint(buffer[count]) ? buffer[count]:'.');
}

//causes crazy output in file
/*for(count = 0; count < sizeof buffer; count++)
{
(int) fwrite(buffer, 1, isprint(buffer[count]), outfile);
}*/

fclose(outfile);
getchar();
return 0;

}- -

- -
Dear friend, we sell all kinds of laptops and guitars . our product
is a quantity best, the price is the lowest in the world, i think you
will be interested in our product . thanks a lot! Our Website:http://
www.prs-123.com/
Msn: pr**********@hotmail.com
mail: pr**********@yahoo.com.cn
thanks for everyone good luck with everyone .
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %
Dear friend, we sell all kinds of laptops and guitars . our product
is a quantity best, the price is the lowest in the world, i think you
will be interested in our product . thanks a lot! Our Website:http://
www.prs-123.com/
Msn: pr**********@hotmail.com
mail: pr**********@yahoo.com.cn
thanks for everyone good luck with everyone .
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %
Dear friend, we sell all kinds of laptops and guitars . our product
is a quantity best, the price is the lowest in the world, i think you
will be interested in our product . thanks a lot! Our Website:http://
www.prs-123.com/
Msn: pr**********@hotmail.com
mail: pr**********@yahoo.com.cn
thanks for everyone good luck with everyone .
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Dear friend, we sell all kinds of laptops and guitars . our product
is a quantity best, the price is the lowest in the world, i think you
will be interested in our product . thanks a lot! Our Website:http://
www.prs-123.com/
Msn: pr**********@hotmail.com
mail: pr**********@yahoo.com.cn
thanks for everyone good luck with everyone .

Jun 13 '07 #11

P: n/a
In article <87************@bsb.me.uk>,
Ben Bacarisse <be********@bsb.me.ukwrote:
>(1) Find out how big the file is. There are two ways to do this in
standard C, but only one that is guaranteed to work.
Perhaps I'm extracting too far out of context, and you were
only intending that to apply to very specific kinds of files,
or to a very specific meaning of "how big" -- but in the general
case, there is no guaranteed way to find file sizes in C.

If you read the file as a text file, then you don't know how much
(if any) space was used for line delimeters. And if it was really
a binary file and you tried to read it as text, there is the possibility
that some sequence of characters in the file (e.g., control-Z) will
be interpreted as signalling the end-of-file.

If you read the file as a binary file, then (if I recall correctly)
trailing nulls in the file are not certain to be preserved.
--
All is vanity. -- Ecclesiastes
Jun 13 '07 #12

P: n/a
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <87************@bsb.me.uk>,
Ben Bacarisse <be********@bsb.me.ukwrote:
>>(1) Find out how big the file is. There are two ways to do this in
standard C, but only one that is guaranteed to work.

Perhaps I'm extracting too far out of context, and you were
only intending that to apply to very specific kinds of files,
or to a very specific meaning of "how big"
That was glossed over in my "this has limitations" remark. I wanted
to simply things as much as possible. It looks like the OP is
starting out in C.
-- but in the general
case, there is no guaranteed way to find file sizes in C.

If you read the file as a text file, then you don't know how much
(if any) space was used for line delimeters. And if it was really
a binary file and you tried to read it as text, there is the possibility
that some sequence of characters in the file (e.g., control-Z) will
be interpreted as signalling the end-of-file.
If it is not safe to treat the file as a binary stream, you only have
one option: read it while counting and then either rewind it or close
it and open it again. Of course, if the file changes (or becomes
unreadable for some reason) you have to report that, but it seems like
a reasonable solution for a beginner.
If you read the file as a binary file, then (if I recall correctly)
trailing nulls in the file are not certain to be preserved.
If the file may be treated as a binary file, then any standard C
program will have to read it and write it subject to whatever
limitations the standard imposes, so I don't really see that as a
problem (in this case). I doubt OP can have been expected to
investigate OS-specific extensions to handle files that are not fully
readable by standard C functions!

I would advise treating the file as a binary stream unless the
specification made that problematic (e.g. if one had to deal with
"lines" in some way). If this (opening as a binary file) is possible
then I would consider it reasonable for a student to either seek to
the end or to read to the end and use ftell to see how many characters
are likely to available after a rewind. Of course, all errors should
be reported, and a read shorter than expected should be dealt with
properly, but all of this is simpler (for a beginner) than doing a
general search and replace while doing buffered reads through a stream.

What is "reasonable" could change with even a slight change in
specification. I'd advice a different strategy if the search string
is constrained within "lines", or if the program should be able to
handle huge files, or non-rewindable streams, or...

--
Ben.
Jun 13 '07 #13

P: n/a
Bill <bi*********@allstate.comwrites:
Yes. It has become wacky. What I'm trying to do is read the contents
of a file into a buffer, find a particular string in the buffer, make
an edit in the found string and write the same file back out.
I suggested on way to go in another sub thread, but let me suggest
another which does not suffer from the ugliness of having to read in
the whole file.

You can read the file one character at a time. When that character
read matches the "next" character in your search string, just update a
count of how many matching characters you have seen. If, when you do
this, you get to the end of the target string, you know you have found
a match and you can print the replacement. When you don't find a
match you just reset your count of matched characters.

Looking back at your post, it is quite possible that this is the way
you were trying to do it. It is certainly a better design than my
other suggestion. By the way, there is nothing wrong with writing
both programs to compare them!

This strategy, will allow you to make your program into a filter so it
would be better *not* to open named input and output files. It should
read stdin and write stdout.

--
Ben.
Jun 13 '07 #14

P: n/a
On Jun 13, 10:28 pm, Bill <bill.war...@allstate.comwrote:
//causes an access violation error
fputc(outfile, isprint(buffer[count]) ? buffer[count]:'.');
Hint: the prototype for fputc is:
int fputc(int c, FILE *stream);

If you didn't get a compiler warning at least on this
line, you should really turn up your warning level.

If gcc is your compiler then use the switches:
-Wall -Wextra -pedantic

along with either -std=ansi or -std=c99.
//causes crazy output in file
/*for(count = 0; count < sizeof buffer; count++)
{
(int) fwrite(buffer, 1, isprint(buffer[count]), outfile);
}*/
This will fill the file with ones and zeroes
(bytes, not bits!) I suspect you wanted a bit
more substance to the third argument to fwrite.

A couple of other style notes:
printf("%c", isprint(buffer[count]) ? buffer[count]:'.');
putchar(X) seems nicer to me than printf("%c", X).
In fact, you use this ternary expression in several
places in the code so I would like to see it contained
as its own function, e.g.

int ch_printable(int ch) { return isprint(ch) ? ch : '.'; }

and then in your other functions:
putchar( ch_printable( buffer[count] ) );

Another way to go would be to make your function:
int fputc_printable(int ch, FILE *stream);
pfile = fopen ("my.txt" , "r");
while(!feof(pfile))
You should check pfile != NULL immediately after the fopen.
(Others have already explained the problem with feof).

Jun 14 '07 #15

P: n/a
Bill wrote:
Input file contents:
Fred Flinstone 123-456-7890
Barney Rubble 123-789-4561
Yes. It has become wacky. What I'm trying to do is read the contents
of a file into a buffer, find a particular string in the buffer, make
an edit in the found string and write the same file back out.
/* BEGIN one_way.c output */

my.txt open for reading.
my.txt closed.

Original file:
Fred Flinstone 123-456-7890
Barney Rubble 123-789-4561

my.txt open for writing.
my.txt closed.

New file:
Fred Flinstone KL5-456-7890
Barney Rubble KL5-789-4561

/* END one_way.c output */
/* BEGIN one_way.c */

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

#define STRING "123"
#define SUBSTITUE "KL5"

struct list_node {
struct list_node *next;
void *data;
};

unsigned long max_line_len(FILE *fp);
void list_free(struct list_node *node, void (*free_data)(void *));
int list_fputs(struct list_node *node, FILE *stream);
struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data);
struct list_node *alter_list(struct list_node *head);
char *alter_line(char *line);

int main(void)
{
int rc;
FILE *fp;
char *line;
char *fn = "my.txt";
unsigned long max_length;
struct list_node *head, *tail;

puts("/* BEGIN one_way.c output */\n");
fp = fopen (fn, "r");
if (fp == NULL) {
puts("fp == NULL");
exit(EXIT_SUCCESS);
}
printf("%s open for reading.\n", fn);
max_length = max_line_len(fp);
if (max_length == -1) {
puts("ferror");
exit(EXIT_FAILURE);
}
line = malloc(max_length + 1);
if (line == NULL) {
printf("max_length is %lu\n", max_length);
exit(EXIT_FAILURE);
}
head = tail = NULL;
do {
rc = fscanf(fp, "%[^\n]", line);
if (!feof(fp)) {
getc(fp);
}
switch (rc) {
case 0:
*line = '\0';
case 1:
tail = string_node(&head, tail, line);
if (tail == NULL) {
puts("tail == NULL");
exit(EXIT_FAILURE);
}
default:
break;
}
} while (rc != EOF);
fclose(fp);
printf("%s closed.\n\n", fn);
puts("Original file:");
list_fputs(head, stdout);
if (alter_list(head) == NULL) {
list_free(head, free);
puts("alter_list(head) == NULL");
exit(EXIT_FAILURE);
}
fp = fopen (fn, "w");
if (fp == NULL) {
puts("fp == NULL2");
exit(EXIT_FAILURE);
}
printf("\n%s open for writing.\n", fn);
list_fputs(head, fp);
fclose(fp);
printf("%s closed.\n\n", fn);
puts("New file:");
list_fputs(head, stdout);
list_free(head, free);
puts("\n/* END one_way.c output */");
return 0;
}

struct list_node *alter_list(struct list_node *head)
{
struct list_node *node = head;
char *p;

while (node != NULL) {
p = alter_line(node -data);
if (p != NULL) {
node -data = p;
}
node = node -next;
}
return head;
}

char *alter_line(char *line)
{
char *p;

p = strstr(line, STRING);
if (p != NULL) {
memcpy(p, SUBSTITUE, strlen(SUBSTITUE));
}
return line;
}

unsigned long max_line_len(FILE *fp)
{
int rc;
unsigned long count, max;

count = max = 0;
while ((rc = getc(fp)) != EOF) {
if (rc == '\n') {
if (count max) {
max = count;
}
count = 0;
} else {
++count;
}
}
if (ferror(fp)) {
max = 0lu - 1;
}
rewind(fp);
return max;
}

void list_free(struct list_node *node, void (*free_data)(void *))
{
struct list_node *next_node;

while (node != NULL) {
next_node = node -next;
free_data(node -data);
free(node);
node = next_node;
}
}

int list_fputs(struct list_node *node, FILE *stream)
{
while (node != NULL) {
if (fputs(node -data, stream) == EOF) {
return EOF;
}
if (putc('\n', stream) == EOF) {
return EOF;
}
node = node -next;
}
return '\n';
}

struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data)
{
struct list_node *node;

node = malloc(sizeof *node);
if (node != NULL) {
node -next = NULL;
node -data = malloc(strlen(data) + 1);
if (node -data != NULL) {
strcpy(node -data, data);
if (*head == NULL) {
*head = node;
} else {
tail -next = node;
}
} else {
free(node);
node = NULL;
}
}
return node;
}

/* END one_way.c */
--
pete
Jun 14 '07 #16

P: n/a
pete wrote:
>
Bill wrote:
Input file contents:
Fred Flinstone 123-456-7890
Barney Rubble 123-789-4561
Yes. It has become wacky.
What I'm trying to do is read the contents
of a file into a buffer,
find a particular string in the buffer, make
an edit in the found string and write the same file back out.
/* BEGIN one_way.c output */
/* BEGIN another_way.c output */

my.txt open for reading.
my.txt closed.

Original file:
Fred Flinstone 123-456-7890
Barney Rubble 123-789-4561

my.txt open for writing.
my.txt closed.

New file:
Fred Flinstone KL5-456-7890
Barney Rubble KL5-789-4561

/* END another_way.c output */
/* BEGIN another_way.c */

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

#define STRING "123"
#define SUBSTITUE "KL5"

struct list_node {
struct list_node *next;
void *data;
};

int get_line(char **lineptr, size_t *n, FILE *stream);
void list_free(struct list_node *node, void (*free_data)(void *));
int list_fputs(struct list_node *node, FILE *stream);
struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data);
struct list_node *alter_list(struct list_node *head);
char *alter_line(char *line);

int main(void)
{
int rc;
size_t size;
FILE *fp;
char *line;
char *fn = "my.txt";
struct list_node *head, *tail;

puts("/* BEGIN another_way.c output */\n");
fp = fopen (fn, "r");
if (fp == NULL) {
puts("fp == NULL");
exit(EXIT_SUCCESS);
}
printf("%s open for reading.\n", fn);
line = NULL;
size = 0;
head = tail = NULL;
for (;;) {
rc = get_line(&line, &size, fp);
if (rc 0) {
tail = string_node(&head, tail, line);
if (tail == NULL) {
puts("tail = NULL");
exit(EXIT_FAILURE);
}
} else {
break;
}
}
free(line);
line = NULL;
size = 0;
fclose(fp);
printf("%s closed.\n\n", fn);
puts("Original file:");
list_fputs(head, stdout);
if (alter_list(head) == NULL) {
list_free(head, free);
puts("alter_list(head) == NULL");
exit(EXIT_FAILURE);
}
fp = fopen (fn, "w");
if (fp == NULL) {
puts("fp == NULL2");
exit(EXIT_FAILURE);
}
printf("\n%s open for writing.\n", fn);
list_fputs(head, fp);
fclose(fp);
printf("%s closed.\n\n", fn);
puts("New file:");
list_fputs(head, stdout);
list_free(head, free);
puts("\n/* END another_way.c output */");
return 0;
}

struct list_node *alter_list(struct list_node *head)
{
struct list_node *node = head;
char *p;

while (node != NULL) {
p = alter_line(node -data);
if (p != NULL) {
node -data = p;
}
node = node -next;
}
return head;
}

char *alter_line(char *line)
{
char *p;

p = strstr(line, STRING);
if (p != NULL) {
memcpy(p, SUBSTITUE, strlen(SUBSTITUE));
}
return line;
}

void list_free(struct list_node *node, void (*free_data)(void *))
{
struct list_node *next_node;

while (node != NULL) {
next_node = node -next;
free_data(node -data);
free(node);
node = next_node;
}
}

int list_fputs(struct list_node *node, FILE *stream)
{
while (node != NULL) {
if (fputs(node -data, stream) == EOF) {
return EOF;
}
if (putc('\n', stream) == EOF) {
return EOF;
}
node = node -next;
}
return '\n';
}

struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data)
{
struct list_node *node;

node = malloc(sizeof *node);
if (node != NULL) {
node -next = NULL;
node -data = malloc(strlen(data) + 1);
if (node -data != NULL) {
strcpy(node -data, data);
if (*head == NULL) {
*head = node;
} else {
tail -next = node;
}
} else {
free(node);
node = NULL;
}
}
return node;
}

int get_line(char **lineptr, size_t *n, FILE *stream)
{
int rc;
void *p;
size_t count;

count = 0;
while ((rc = getc(stream)) != EOF) {
if (count != -1) {
++count;
}
if (count + 2 *n) {
p = realloc(*lineptr, count + 2);
if (p == NULL) {
if (*n count) {
if (rc != '\n') {
(*lineptr)[count] = '\0';
(*lineptr)[count - 1] = (char)rc;
} else {
(*lineptr)[count - 1] = '\0';
}
} else {
if (*n != 0) {
**lineptr = '\0';
}
ungetc(rc, stream);
}
count = 0;
break;
}
*lineptr = p;
*n = count + 2;
}
if (rc == '\n') {
(*lineptr)[count - 1] = '\0';
break;
}
(*lineptr)[count - 1] = (char)rc;
}
if (rc != EOF) {
rc = count INT_MAX ? INT_MAX : count;
} else {
if (*n count) {
(*lineptr)[count] = '\0';
}
}
return rc;
}

/* END another_way.c */
--
pete
Jun 14 '07 #17

P: n/a
Old Wolf <ol*****@inspire.net.nzwrites:
On Jun 13, 10:28 pm, Bill <bill.war...@allstate.comwrote:
[...]
> //causes crazy output in file
/*for(count = 0; count < sizeof buffer; count++)
{
(int) fwrite(buffer, 1, isprint(buffer[count]), outfile);
}*/

This will fill the file with ones and zeroes
(bytes, not bits!) I suspect you wanted a bit
more substance to the third argument to fwrite.
Not necessarily. isprint() returns 0 if its argument is not a
printing character, but it can return any non-zero (i.e., true) value
if it is.

If you really want a 0 or 1 value for some reason, you can use
isprint(buffer[count]) ? 1 : 0
or
!!isprint(buffer[count])

And what the heck is the point of casting the result of fwrite() to
int before discarding it? fwrite() returns a size_t result. If you
want to ignore the result, no cast is needed (though you can cast to
void if you want to be explicit). But you should always check the
result anyway.

[snip]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 14 '07 #18

P: n/a
On Jun 14, 12:49 pm, Keith Thompson <k...@mib.orgwrote:
On Jun 13, 10:28 pm, Bill <bill.war...@allstate.comwrote:
[...]
//causes crazy output in file
/*for(count = 0; count < sizeof buffer; count++)
{
(int) fwrite(buffer, 1, isprint(buffer[count]), outfile);
}*/

Not necessarily. isprint() returns 0 if its argument is not a
printing character, but it can return any non-zero (i.e., true) value
if it is.
So the above code could write any amount of
extra garbage into the file, as well as the
desired output.
And what the heck is the point of casting the result of fwrite() to
int before discarding it? fwrite() returns a size_t result. If you
want to ignore the result, no cast is needed (though you can cast to
void if you want to be explicit). But you should always check the
result anyway.
I suppose he's using a lint tool that warns about
unused return values. Although he does seem to
have a penchant for useless casts.
Jun 14 '07 #19

P: n/a
Ben Bacarisse wrote:
Bill <bi*********@allstate.comwrites:
>Yes. It has become wacky. What I'm trying to do is read the
contents of a file into a buffer, find a particular string in
the buffer, make an edit in the found string and write the same
file back out.

I suggested on way to go in another sub thread, but let me suggest
another which does not suffer from the ugliness of having to read
in the whole file.

You can read the file one character at a time. When that character
read matches the "next" character in your search string, just update a
count of how many matching characters you have seen. If, when you do
this, you get to the end of the target string, you know you have found
a match and you can print the replacement. When you don't find a
match you just reset your count of matched characters.
Try this. It's somewhat simpler (and faster and bufferless).

/*
Leor Zolman wrote:
On 25 Feb 2004 07:34:40 -0800, jo**@ljungh.se (spike) wrote:
>Im trying to write a program that should read through a binary
file searching for the character sequence "\name\"

Then it should read the characters following the "\name\"
sequence until a NULL character is encountered.

But when my program runs it gets a SIGSEGV (Segmentation
vioalation) signal.

Whats wrong? And is there a better way than mine to solve
this task (most likely)

I think so. Here's a version I just threw together:
*/

/* And heres another throw -- binfsrch.c by CBF */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>

/* The difference between a binary and a text file, on read,
is the conversion of end-of-line delimiters. What those
delimiters are does not affect the action. In some cases
the presence of 0x1a EOF markers (MsDos) does.

This is a version of Knuth-Morris-Pratt algorithm. The
point of using this is to avoid any backtracking in file
reading, and thus avoiding any use of buffer arrays.
*/

size_t chrcount; /* debuggery, count of input chars, zeroed */

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

/* Almost straight out of Sedgewick */
/* The next array indicates what index in id should next be
compared to the current char. Once the (lgh - 1)th char
has been successfully compared, the id has been found.
The array is formed by comparing id to itself. */
void initnext(int *next, const char *id, int lgh)
{
int i, j;

assert(lgh 0);
next[0] = -1; i = 0; j = -1;
while (i < lgh) {
while ((j >= 0) && (id[i] != id[j])) j = next[j];
i++; j++;
next[i] = j;
}
#if (0)
for (i = 0; i < lgh; i++)
printf("id[%d] = '%c' next[%d] = %d\n",
i, id[i], i, next[i]);
#endif
} /* initnext */

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

/* reads f without rewinding until either EOF or *marker
has been found. Returns EOF if not found. At exit the
last matching char has been read, and no further. */
int kmpffind(const char *marker, int lgh, int *next, FILE *f)
{
int j; /* char position in marker to check */
int ch; /* current char */

assert(lgh 0);
j = 0;
while ((j < lgh) && (EOF != (ch = getc(f)))) {
chrcount++;
while ((j >= 0) && (ch != marker[j])) j = next[j];
j++;
}
return ch;
} /* kmpffind */

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

/* Find marker in f, display following printing chars
up to some non printing character or EOF */
int binfsrch(const char *marker, FILE *f)
{
int *next;
int lgh;
int ch;
int items; /* count of markers found */

lgh = strlen(marker);
if (!(next = malloc(lgh * sizeof *next))) {
puts("No memory");
exit(EXIT_FAILURE);
}
else {
initnext(next, marker, lgh);
items = 0;
while (EOF != kmpffind(marker, lgh, next, f)) {
/* found, take appropriate action */
items++;
printf("%d %s : \"", items, marker);
while (isprint(ch = getc(f))) {
chrcount++;
putchar(ch);
}
puts("\"");
if (EOF == ch) break;
else chrcount++;
}
free(next);
return items;
}
} /* binfsrch */

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

int main(int argc, char **argv)
{
FILE *f;

f = stdin;
if (3 == argc) {
if (!(f = fopen(argv[2], "rb"))) {
printf("Can't open %s\n", argv[2]);
exit(EXIT_FAILURE);
}
argc--;
}
if (2 != argc) {
puts("Usage: binfsrch name [binaryfile]");
puts(" (file defaults to stdin text mode)");
}
else if (binfsrch(argv[1], f)) {
printf("\"%s\" : found\n", argv[1]);
}
else printf("\"%s\" : not found\n", argv[1]);
printf("%lu chars\n", (unsigned long)chrcount);
return 0;
} /* main binfsrch */

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 14 '07 #20

P: n/a
Old Wolf <ol*****@inspire.net.nzwrites:
On Jun 14, 12:49 pm, Keith Thompson <k...@mib.orgwrote:
On Jun 13, 10:28 pm, Bill <bill.war...@allstate.comwrote:
[...]
> //causes crazy output in file
/*for(count = 0; count < sizeof buffer; count++)
{
(int) fwrite(buffer, 1, isprint(buffer[count]), outfile);
}*/

Not necessarily. isprint() returns 0 if its argument is not a
printing character, but it can return any non-zero (i.e., true) value
if it is.

So the above code could write any amount of
extra garbage into the file, as well as the
desired output.
Whoops, I was paying attention to the value of the expression but not
to how it's being used. Yes, since the 3rd argument to fwrite is the
number of elements to write (and the 2nd is the size in bytes of each
element), it will *attempt* to write some arbirary amount of data to
the file. It will attempt to read that data from buffer, which very
likely isn't big enough, causing undefined behavior. That's probably
the cause of the "crazy output".

I was going to say that this will usually work, since isprint() in
practice will probably return either 0 or 1, but that's not the case.
In one implementation I just tried, it consistently returns 0 or
16384. I think this is a result of the table lookup method used
internally by the implementation <OT>glibc</OT>.

Even if isprint() always returned 0 or 1, passing 0 or 1 as the third
argument to fwrite is a rather odd technique. If you don't want to
write anything it probably makes more sense just not to call fwrite.

[snip]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 14 '07 #21

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Ben Bacarisse wrote:
>Bill <bi*********@allstate.comwrites:
>>Yes. It has become wacky. What I'm trying to do is read the
contents of a file into a buffer, find a particular string in
the buffer, make an edit in the found string and write the same
file back out.

I suggested on way to go in another sub thread, but let me suggest
another which does not suffer from the ugliness of having to read
in the whole file.

You can read the file one character at a time. When that character
read matches the "next" character in your search string, just update a
count of how many matching characters you have seen. If, when you do
this, you get to the end of the target string, you know you have found
a match and you can print the replacement. When you don't find a
match you just reset your count of matched characters.

Try this. It's somewhat simpler (and faster and bufferless).

/* And heres another throw -- binfsrch.c by CBF */
<Knuth-Morris-Pratt implementation snipped>

Only three problems with this:

(1) The OP is starting out in C. Do you think an implementation of
KMP is simpler than the one-char at a time match I suggested they try
to implement?

(2) It does not do what they said they were trying to do. They wanted
a search and replace and with your version of KMP it is tricky to
convert to a version that echos up to the start of a match. Not that
hard for us, but were you suggesting a beginner should try to do it?

(3) It is wrong -- specifically it invokes the dreaded UB by writing
outside the bounds of an array.

--
Ben.
Jun 14 '07 #22

P: n/a
Ben Bacarisse wrote:
CBFalconer <cb********@yahoo.comwrites:
.... snip ...
>
(3) It is wrong -- specifically it invokes the dreaded UB by
writing outside the bounds of an array.
Oh? Where? I believe you are mistaken.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 14 '07 #23

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Ben Bacarisse wrote:
>CBFalconer <cb********@yahoo.comwrites:
... snip ...
>>
(3) It is wrong -- specifically it invokes the dreaded UB by
writing outside the bounds of an array.

Oh? Where? I believe you are mistaken.
while (i < lgh) {
while ((j >= 0) && (id[i] != id[j])) j = next[j];
i++; j++;
next[i] = j; /* <== Here. 'next' is of size 'lgh'. */
}

The program writes to only one array and in only one place so there are
not may places to check!

--
Ben.
Jun 14 '07 #24

P: n/a
Ben Bacarisse wrote:
CBFalconer <cb********@yahoo.comwrites:
>Ben Bacarisse wrote:
>>CBFalconer <cb********@yahoo.comwrites:
... snip ...
>>>
(3) It is wrong -- specifically it invokes the dreaded UB by
writing outside the bounds of an array.

Oh? Where? I believe you are mistaken.

while (i < lgh) {
while ((j >= 0) && (id[i] != id[j])) j = next[j];
i++; j++;
next[i] = j; /* <== Here. 'next' is of size 'lgh'. */
}

The program writes to only one array and in only one place so
there are not may places to check!
Bah humbug. Looks like I goofed, and the fact that my malloc acts
on the ((length + 15) modulo 16) hid it. I just made the malloc
allocate 1 more byte. Thanks for the correction.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net
--
Posted via a free Usenet account from http://www.teranews.com

Jun 15 '07 #25

This discussion thread is closed

Replies have been disabled for this discussion.