Does C distinguish between a C source file and a text file?

A

amit

Hi guys!I am trying to write a program which will segregate some
selected keywords from a given file.The source code is given alongwith

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

char key_set[][4]={"ami\0","inc\0","lud\0"};
#define MAX_KW_SIZE 10
#define MAX_OCUR 100

struct kbuf_node{
char keyword[MAX_KW_SIZE];
int byte_offset[MAX_OCUR];

}buf_node;


int main(int argc,char *argv[])
{
FILE *fp,*fp_kbuf;
char *s;
int i,offset=0,cnt,FLAG=0;

fp_kbuf=fopen("buf.txt","wb"); //the file in which i will save the
keywords and their byte offsets
for(i=0;i<=2;i++)
{
cnt=0;
offset=0;
s=(char*)malloc(sizeof(key_set));
fp=fopen(argv[0],"rb"); //the master file given as argument

if(fp==NULL)
{
printf("Unable to open file");
exit(0);
}
while(fgets(s,sizeof(key_set),fp)!=NULL)
{
//printf("Before setpos%u\n",ftell(fp));
offset++;
if(strcmp(s,key_set)==0)
{
//printf("%s\t %d\n",s,offset);
if(FLAG==0)
{
strcpy(buf_node.keyword,s);
FLAG=1;
}
buf_node.byte_offset[cnt++]=offset;

}
fsetpos(fp,&offset);
//printf("After setpos %u\n",fp);
}

//write to the kw-buffer file
fwrite(&buf_node,sizeof(buf_node),1,fp_kbuf);
FLAG=0;

fclose(fp);
}
fclose(fp_kbuf);
fp_kbuf=fopen("buf.txt","rb");
while(fread(&buf_node,sizeof(buf_node),1,fp_kbuf)>0)
{
printf("\n%s\t",buf_node.keyword);
for(i=0;i<cnt;i++)
printf("%d\t",buf_node.byte_offset);
printf("\n");
}

return 0;
}


After compiling the file when i run the program using a C source file
as my file then it works fine.BUt with a text file it only reports the
first occurence of the keywords!I am using gcc under FC5
 
F

Flash Gordon

amit said:
Hi guys!I am trying to write a program which will segregate some
selected keywords from a given file.The source code is given alongwith

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

Spaces are given away free with cornflakes so you don't need to save
them For better readability try
#include <stdio.h>
#include said:
char key_set[][4]={"ami\0","inc\0","lud\0"};

You don't need to specify the \0. Also, as this is a fixed list and you
don't want to modify the data it would be better to simply use:
const char *key_set[]={"ami","inc","lud"};

#define MAX_KW_SIZE 10
#define MAX_OCUR 100

struct kbuf_node{
char keyword[MAX_KW_SIZE];
int byte_offset[MAX_OCUR];

}buf_node;

Using globals is generally a bad idea.
int main(int argc,char *argv[])
{
FILE *fp,*fp_kbuf;
char *s;
int i,offset=0,cnt,FLAG=0;

Traditionally all upper case names are only used for macros and
enumerations.
fp_kbuf=fopen("buf.txt","wb"); //the file in which i will save the
keywords and their byte offsets

Please don't use // style comments on Usenet. They don't survive line
wrapping as you can see. Also they are not supported by C89 the most
commonly implemented C standard.
for(i=0;i<=2;i++)

Magic numbers are bad. They make maintenance harder.
for(i=0; i < (sizeof key_set / sizeof key_set[0]); i++)
{
cnt=0;
offset=0;
s=(char*)malloc(sizeof(key_set));


Don't cast the return value of malloc it isn't required. The reason the
compiler complained at you without the cast is because you failed to
include stdlib.h. This is a serious error and causes the code to fail on
some modern platforms.

Also you never free the memory so each time round the loop you leak memory.

In any case, since this is a constant size why did you not just allocate
an array of the appropriate size?
fp=fopen(argv[0],"rb"); //the master file given as argument

argv[0] is the name of the executable, or some variation of it, are you
sure your didn't mean argv[1] after checking that argc is at least 2?
if(fp==NULL)
{
printf("Unable to open file");
exit(0);

Better would be to signal an error rather than success!
exit(EXIT_FAILURE);
}
while(fgets(s,sizeof(key_set),fp)!=NULL)
{
//printf("Before setpos%u\n",ftell(fp));
offset++;
if(strcmp(s,key_set)==0)
{
//printf("%s\t %d\n",s,offset);
if(FLAG==0)
{
strcpy(buf_node.keyword,s);
FLAG=1;
}
buf_node.byte_offset[cnt++]=offset;

}
fsetpos(fp,&offset);


The second argument to fsetpos is a pointer to fpos_t NOT a pointer to
int. On some implementations fpos_t could be a long or a struct and thus
severely break your code.
//printf("After setpos %u\n",fp);
}

//write to the kw-buffer file
fwrite(&buf_node,sizeof(buf_node),1,fp_kbuf);
FLAG=0;

fclose(fp);
}
fclose(fp_kbuf);
fp_kbuf=fopen("buf.txt","rb");
while(fread(&buf_node,sizeof(buf_node),1,fp_kbuf)>0)
{
printf("\n%s\t",buf_node.keyword);
for(i=0;i<cnt;i++)
printf("%d\t",buf_node.byte_offset);
printf("\n");
}

return 0;
}


After compiling the file when i run the program using a C source file
as my file then it works fine.BUt with a text file it only reports the
first occurence of the keywords!I am using gcc under FC5


Try turning up the warnings and actually fixing the things it complains
about. Start with considering all the bits I have pointed out that are
wrong. Although you approach does not seem very efficient to me anyway.
 
A

amit

hi Flash!
If u cud suggest a more efficient way of doing this?I am really sory
for the goof-ups!I am new to usenet!plz excuse me!

Flash said:
amit said:
Hi guys!I am trying to write a program which will segregate some
selected keywords from a given file.The source code is given alongwith

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

Spaces are given away free with cornflakes so you don't need to save
them For better readability try
#include <stdio.h>
#include said:
char key_set[][4]={"ami\0","inc\0","lud\0"};

You don't need to specify the \0. Also, as this is a fixed list and you
don't want to modify the data it would be better to simply use:
const char *key_set[]={"ami","inc","lud"};

#define MAX_KW_SIZE 10
#define MAX_OCUR 100

struct kbuf_node{
char keyword[MAX_KW_SIZE];
int byte_offset[MAX_OCUR];

}buf_node;

Using globals is generally a bad idea.
int main(int argc,char *argv[])
{
FILE *fp,*fp_kbuf;
char *s;
int i,offset=0,cnt,FLAG=0;

Traditionally all upper case names are only used for macros and
enumerations.
fp_kbuf=fopen("buf.txt","wb"); //the file in which i will save the
keywords and their byte offsets

Please don't use // style comments on Usenet. They don't survive line
wrapping as you can see. Also they are not supported by C89 the most
commonly implemented C standard.
for(i=0;i<=2;i++)

Magic numbers are bad. They make maintenance harder.
for(i=0; i < (sizeof key_set / sizeof key_set[0]); i++)
{
cnt=0;
offset=0;
s=(char*)malloc(sizeof(key_set));


Don't cast the return value of malloc it isn't required. The reason the
compiler complained at you without the cast is because you failed to
include stdlib.h. This is a serious error and causes the code to fail on
some modern platforms.

Also you never free the memory so each time round the loop you leak memory.

In any case, since this is a constant size why did you not just allocate
an array of the appropriate size?
fp=fopen(argv[0],"rb"); //the master file given as argument

argv[0] is the name of the executable, or some variation of it, are you
sure your didn't mean argv[1] after checking that argc is at least 2?
if(fp==NULL)
{
printf("Unable to open file");
exit(0);

Better would be to signal an error rather than success!
exit(EXIT_FAILURE);
}
while(fgets(s,sizeof(key_set),fp)!=NULL)
{
//printf("Before setpos%u\n",ftell(fp));
offset++;
if(strcmp(s,key_set)==0)
{
//printf("%s\t %d\n",s,offset);
if(FLAG==0)
{
strcpy(buf_node.keyword,s);
FLAG=1;
}
buf_node.byte_offset[cnt++]=offset;

}
fsetpos(fp,&offset);


The second argument to fsetpos is a pointer to fpos_t NOT a pointer to
int. On some implementations fpos_t could be a long or a struct and thus
severely break your code.
//printf("After setpos %u\n",fp);
}

//write to the kw-buffer file
fwrite(&buf_node,sizeof(buf_node),1,fp_kbuf);
FLAG=0;

fclose(fp);
}
fclose(fp_kbuf);
fp_kbuf=fopen("buf.txt","rb");
while(fread(&buf_node,sizeof(buf_node),1,fp_kbuf)>0)
{
printf("\n%s\t",buf_node.keyword);
for(i=0;i<cnt;i++)
printf("%d\t",buf_node.byte_offset);
printf("\n");
}

return 0;
}


After compiling the file when i run the program using a C source file
as my file then it works fine.BUt with a text file it only reports the
first occurence of the keywords!I am using gcc under FC5


Try turning up the warnings and actually fixing the things it complains
about. Start with considering all the bits I have pointed out that are
wrong. Although you approach does not seem very efficient to me anyway.
 
A

Al Balmer

If u cud suggest a more efficient way of doing this?I am really sory
for the goof-ups!I am new to usenet!plz excuse me!

You can start by actually reading and understanding what Flash Gordon
wrote. Next, when you come back with more questions, take care to
intersperse your remarks after the text they refer to, rather than
top-posting. Also, stop the baby talk. Use "you", "could", and
"please" instead of "u", "cud", and "plz."
 
K

Keith Thompson

amit said:
hi Flash!
If u cud suggest a more efficient way of doing this?I am really sory
for the goof-ups!I am new to usenet!plz excuse me!
[...]

Don't top-post. Your response goes *below* any quoted text you're
replying to, or interspersed with it. See most of the articles in
this newsgroup for examples. See also
<http://www.caliburn.nl/topposting.html>.

Don't use silly abbreviations. Take the time to spell out words, and
add a space or two after each sentence. For example:

If you could suggest a more efficient way of doing this? I am
really sorry for the goof-ups. I am new to Usenet. Please excuse
me.

It makes it *much* easier to read.

Finally, Flash already gave you some very good advice in the article
you replied to. Try following it before you ask the same question
again.
 

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
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top