FILE Operations

S

Steve

Can someone write a sample c code showing how one can find an instance of a
word or a char in a file (including opening and closing a file)? Thanks
 
E

Emmanuel Delahaye

Steve wrote on 28/07/04 :
Can someone write a sample c code showing how one can find an instance of a
word or a char in a file (including opening and closing a file)? Thanks

This is going too far. You have to write the code yourself.

Hints: Open your C book.
 
J

Jackie

Can someone write a sample c code showing how one can find an instance of
a
word or a char in a file (including opening and closing a file)? Thanks
Hi Steve,
This code lets you count the instances of a given char:
#include <stdio.h>
#include <string.h>
int main()
{
const char fileName[] = "fileName.txt";
const char toCount = 'f';

FILE* f = fopen(fileName, "r");
if(!f)
{
printf("File NOT found\n");
exit(0);
}

char s[100];
memset(s, '\0', 100);
int count = 0;
while (fgets(s, 100, f))
{
char * q = &s[0];
for(; *q != '\0'; q++)
{
if(*q == toCount)
count++;
}
printf("%s", s);/* to print each set of chars*/
}
memset(s, '\0', 100);
printf("You have %d \"%c's\"\n", count, toCount);
fclose(f);

return 0;
}
 
J

jacob navia

Please don't do other's home work...
They will not learn anything and they will tell their friends:

Just let comp.lang.c people do the homework!
 
E

Emmanuel Delahaye

Jackie wrote on 28/07/04 :

My corrections (-ed-)

/* -ed- reformatted */

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

/* -ed- was missing (exit()) */
#include <stdlib.h>

int main ()
{
const char fileName[] = "fileName.txt";
const char toCount = 'f';

FILE *f = fopen (fileName, "r");

if (!f)
{
printf ("File NOT found\n");
/* -ed-
Semantically incorrect. 0 means OK.
exit (0);
*/
exit (EXIT_FAILURE);

}

/* -ed- block added. Not all compilers are C99 */
{
char s[100];
int count = 0;

/* -ed- Useless. Removed
memset (s, '\0', 100);
*/
/* -ed- Help maintenance. Avoid redundant information...
while (fgets (s, 100, f))
*/
while (fgets (s, sizeof s, f))
{
char *q = &s[0];
for (; *q != '\0'; q++)
{
if (*q == toCount)
count++;
}
printf ("%s", s); /* to print each set of chars */
}

/* -ed- Useless. Removed
memset (s, '\0', 100);
*/
printf ("You have %d \"%c's\"\n", count, toCount);
}
fclose (f);

return 0;
}
 
J

Jackie

This is in response to Emmanuel Delahaye's comments:
memset is needed to set the positions to zero otherwise for the 2nd, 3rd,
.... readings you'll mix it with prior readings. Plus, for printf you'll have
to end with '\0'. stdlib.h is NOT needed for NULL because NULL is actually
0. SO, (char *)0 in that context does the job of NULL and is even better.
 
E

Emmanuel Delahaye

Jackie wrote on 28/07/04 :
This is in response to Emmanuel Delahaye's comments:
memset is needed to set the positions to zero otherwise for the 2nd, 3rd,
... readings you'll mix it with prior readings.

So what? Unless it returns NULL, the fgets() functions makes a valid
string. Always.
Plus, for printf you'll have
to end with '\0'.

Done already by fgets().
stdlib.h is NOT needed for NULL because NULL is actually
0. SO, (char *)0 in that context does the job of NULL and is even better.

I was not concerned by NULL but by the prototype of exit() as
mentionned:

[quoting myself]
 
J

Jackie

Emmanuel Delahaye said:
Jackie wrote on 28/07/04 :

So what? Unless it returns NULL, the fgets() functions makes a valid
string. Always.

Are you saying that fgets() sets all the positions to '\0' before writing to
the same array for subsequent readings? Assume we have char s[10] What if
your 1st line is "123456789" and the second line is "1234" You may not see
it with printf because printf stops as soon as it reaches '\0' but for the
second reading you still have some chars from the 1st because the 1st line
is longer.
 
E

Emmanuel Delahaye

Jackie wrote on 28/07/04 :
Are you saying that fgets() sets all the positions to '\0' before writing to
the same array for subsequent readings?

Certainely not. What the standard says is that a 0 is placed at the end
of the string pointed by the first parameter of fgets() when it doen't
return NULL.

Just reread your C-book.
Assume we have char s[10] What if
your 1st line is "123456789" and the second line is "1234" You may not see
it with printf because printf stops as soon as it reaches '\0' but for the
second reading you still have some chars from the 1st because the 1st line
is longer.

That's plain wrong:

1st line : {'1','2','3','4','5','6','7','8','9',\n}
2nd line : {'1','2','3','4'\n}<EOF>

1st read : {'1','2','3','4','5','6','7','8','9',0} -> "123456789"
2nd read : {'\n',0,'3','4','5','6','7','8','9',0} -> CRLF
3st read : {'1','2','3','4','\n',0,'7','8','9',0} -> "1234"CRLF

I admit that it's not very 'clean' specially if you track the string
with a debugger, but it works correctly and safely.
 
A

Alex Fraser

Emmanuel Delahaye said:
Jackie wrote on 28/07/04 :
Assume we have char s[10] What if
your 1st line is "123456789" and the second line is "1234" You may not
see it with printf because printf stops as soon as it reaches '\0' but
for the second reading you still have some chars from the 1st because
the 1st line is longer.

That's plain wrong:

No, it's perfectly correct, as you go on to show. But interpreting the array
of char as a string means ignoring everything after the first '\0', so any
"left over" chars simply don't matter.
1st line : {'1','2','3','4','5','6','7','8','9',\n}
2nd line : {'1','2','3','4'\n}<EOF>

1st read : {'1','2','3','4','5','6','7','8','9',0} -> "123456789"
2nd read : {'\n',0,'3','4','5','6','7','8','9',0} -> CRLF
3st read : {'1','2','3','4','\n',0,'7','8','9',0} -> "1234"CRLF

I admit that it's not very 'clean' specially if you track the string
with a debugger, but it works correctly and safely.

Depends on the debugger, I guess.

Alex
 
A

Alan Balmer

Can someone write a sample c code showing how one can find an instance of a
word or a char in a file (including opening and closing a file)? Thanks
You will have to learn to do your own homework. If you have a problem,
give it your best try and post it here, and many readers will be glad
to help.

Of course, there is always someone (usually a newer group member) who
is willing to post a solution, as you see elsethread. Use his
contribution if you want, but don't expect a good grade - it's not
very good code.
 
C

Christopher Benson-Manica

Emmanuel Delahaye said:
while (fgets (s, sizeof s, f))
{
char *q = &s[0];
for (; *q != '\0'; q++)
{
if (*q == toCount)
count++;
}
printf ("%s", s); /* to print each set of chars */
}

Why not let strchr do some of the work for you?

while( fgets(s,sizeof s,f) ) {
char *q;
for( q=strchr(s,toCount); q != NULL; q=strchr(q+1,toCount) )
count++;
printf( "%s\n", s );
}
 
M

Malcolm

Jackie said:
Are you saying that fgets() sets all the positions to '\0' before writing to
the same array for subsequent readings? Assume we have char s[10] What if
your 1st line is "123456789" and the second line is "1234" You may not see
it with printf because printf stops as soon as it reaches '\0' but for the
second reading you still have some chars from the 1st because the 1st line
is longer.
fgets() will NUL-terminate the string it puts into your buffer. There may be
garbage left after the NUL, but this doesn't matter.

You will sometimes see professional programmers memsetting character buffers
to zero for added safety, but the general consensus is that this isn't
necessary.
 
G

Gordon Burditt

Are you saying that fgets() sets all the positions to '\0' before writing
to
the same array for subsequent readings? Assume we have char s[10] What if
your 1st line is "123456789" and the second line is "1234" You may not see
it with printf because printf stops as soon as it reaches '\0' but for the
second reading you still have some chars from the 1st because the 1st line
is longer.
fgets() will NUL-terminate the string it puts into your buffer. There may be
garbage left after the NUL, but this doesn't matter.

You will sometimes see professional programmers memsetting character buffers
to zero for added safety, but the general consensus is that this isn't
necessary.

It is often useful for security and testing purposes to force the
unused portion of a character buffer to be set to nul characters
BEFORE WRITING THE BUFFER TO A FILE. First, the garbage after the
end of the string may be something sensitive you don't want recorded
in a file. Second, it is often useful for things such as regression
testing to ensure that the same input generates the same output.
And garbage rarely compresses as well as a block of nul characters.

Now, there are arguments against writing structures containing
character buffers to a file: the padding isn't portable, and it
takes up more space than just writing the string. There's also all
the integer size and endian issues if the structure has members
other than character arrays. On the other hand, seeking to a
specific structure and updating it in place is possible (and possibly
MUCH faster than re-writing the whole file), and a file load/dump
program can handle issues of moving the data to a different system.

Gordon L. Burditt
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,826
Members
47,371
Latest member
Brkaa

Latest Threads

Top