9 Replies - 588 Views - Last Post: 13 May 2013 - 09:04 PM Rate Topic: -----

#1 lisa101  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 22-April 13

C program with FILES..it crashes

Posted 10 May 2013 - 01:41 AM

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

/* convert word to lower case */
void word_tolower(char s[], char t[]) { 
   int i = 0;
   while(s[i] != '\0') {
      t[i] = tolower(s[i]);
      i++;
   }

   t[i] = '\0';
}

/*remove new line character from string obtained used fgets*/
void remove_newline(char s[], char t[]) { 
   int i = 0;
   while(s[i] != '\n'){
      t[i] = s[i];
      i++;
   }
   t[i] = '\0';
} 

int main() {
   char line[80], line2[80];
   char filename[40];
   char word[20], word1[20], word2[20], lword1[20], lword2[20];
   int i, j, wordcount1, wordcount2, linecount;
	
	FILE *fp;
	
	printf("Enter the first word: ");
   gets(word1);
   word_tolower(word1, lword1);
   
   printf("Enter the second word: ");
   gets(word2);
   word_tolower(word2, lword2);

   printf("Enter the name of the text file: ");
   gets(filename);

   fp = fopen(filename, "r");

   wordcount1 = wordcount2 = linecount = 0;
  
   while(!feof(fp)) {
      linecount++;
      fgets(line, 79, fp); /* note that there will be a '\n' before the final '\0' */
      remove_newline(line, line2); /* remove '\n' for printing purposes */
      i = j = 0;
      
      while(line[i] != '\0') {
        if (line[i] != ' ' && line[i] != '.' && line[i] != '\n') {
           word[j] = tolower(line[i]);
           j++;
			}else{
           word[j] = '\0';
           j = 0;
           if(!strcmp(word, lword1)) { 
              wordcount1++;
              if (wordcount1 == 1) {
                 printf("The word \'%s\' first appears in line %d which is:\n%s\n", word1, linecount, line2); 
              }
           }
           else if (!strcmp(word, lword2)) {
              wordcount2++;
              if (wordcount2 == 1){
                 printf("The word \'%s\' first appears in line %d which is:\n%s\n", word2, linecount, line2); 
               }
            }
         }
        i++;
      }      
   }

   if(wordcount1 > 0){
      printf("The word '%s' appears %d time(s) in the file.", word1, wordcount1);
   }else{
      printf("The word '%s' does not appear in the file.", word1);
   }

   if(wordcount2 > 0) {
      printf("\nThe word '%s' appears %d time(s) in the file.", word2, wordcount2);
   }else{
      printf("\nThe word '%s' does not appear in the file.", word2);
   }
   return 0;
}



//my program keeps on crashing when its trying to do the if(wordcount1>0) and if(wordcount2>0);
//I don't know where i'm going wrong??

This post has been edited by JackOfAllTrades: 10 May 2013 - 03:40 AM
Reason for edit:: Added code tags


Is This A Good Question/Topic? 0
  • +

Replies To: C program with FILES..it crashes

#2 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6092
  • View blog
  • Posts: 23,613
  • Joined: 23-August 08

Re: C program with FILES..it crashes

Posted 10 May 2013 - 03:42 AM

First off, C# is NOT the same as C. Moved to C/C++.

Second, when you post code...USE CODE TAGS!!!

:code:/>/>

Third, STOP USING gets! It is unsafe and should never be used: http://www.gidnetwork.com/b-56.html
You use fgets elsewhere, you should use it always.
Was This Post Helpful? 0
  • +
  • -

#3 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6092
  • View blog
  • Posts: 23,613
  • Joined: 23-August 08

Re: C program with FILES..it crashes

Posted 10 May 2013 - 03:57 AM

It would be helpful if you provided some input and output that causes the crash, but consider this in your remove_newline function. What happens if there's no newline?
Was This Post Helpful? 1
  • +
  • -

#4 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: C program with FILES..it crashes

Posted 11 May 2013 - 01:10 AM

View Postlisa101, on 10 May 2013 - 04:41 AM, said:

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

/* convert word to lower case */
void word_tolower(char s[], char t[]) { 
   int i = 0;
   while(s[i] != '\0') {
      t[i] = tolower(s[i]);
      i++;
   }

   t[i] = '\0';
}

/*remove new line character from string obtained used fgets*/
void remove_newline(char s[], char t[]) { 
   int i = 0;
   while(s[i] != '\n'){
      t[i] = s[i];
      i++;
   }
   t[i] = '\0';
} 

int main() {
   char line[80], line2[80];
   char filename[40];
   char word[20], word1[20], word2[20], lword1[20], lword2[20];
   int i, j, wordcount1, wordcount2, linecount;
	
	FILE *fp;
	
	printf("Enter the first word: ");
   gets(word1);
   word_tolower(word1, lword1);
   
   printf("Enter the second word: ");
   gets(word2);
   word_tolower(word2, lword2);

   printf("Enter the name of the text file: ");
   gets(filename);

   fp = fopen(filename, "r");

   wordcount1 = wordcount2 = linecount = 0;
  
   while(!feof(fp)) {
      linecount++;
      fgets(line, 79, fp); /* note that there will be a '\n' before the final '\0' */
      remove_newline(line, line2); /* remove '\n' for printing purposes */
      i = j = 0;
      
      while(line[i] != '\0') {
        if (line[i] != ' ' && line[i] != '.' && line[i] != '\n') {
           word[j] = tolower(line[i]);
           j++;
			}else{
           word[j] = '\0';
           j = 0;
           if(!strcmp(word, lword1)) { 
              wordcount1++;
              if (wordcount1 == 1) {
                 printf("The word \'%s\' first appears in line %d which is:\n%s\n", word1, linecount, line2); 
              }
           }
           else if (!strcmp(word, lword2)) {
              wordcount2++;
              if (wordcount2 == 1){
                 printf("The word \'%s\' first appears in line %d which is:\n%s\n", word2, linecount, line2); 
               }
            }
         }
        i++;
      }      
   }

   if(wordcount1 > 0){
      printf("The word '%s' appears %d time(s) in the file.", word1, wordcount1);
   }else{
      printf("The word '%s' does not appear in the file.", word1);
   }

   if(wordcount2 > 0) {
      printf("\nThe word '%s' appears %d time(s) in the file.", word2, wordcount2);
   }else{
      printf("\nThe word '%s' does not appear in the file.", word2);
   }
   return 0;
}



//my program keeps on crashing when its trying to do the if(wordcount1>0) and if(wordcount2>0);
//I don't know where i'm going wrong??


This may help you get started ...

/* convert word to lower case */
char* strToLower( char* s )
{
    char* p = s;
    while( *p )
    {
        *p = tolower( *p );
        ++p;
    }
    return s;
}



/* remove new line character from string obtained used fgets and stdin */
char* fixFgets( char* s )
{
    char* p = strchr( s, '\n' );
    if( p ) *p = '\0';
    else while( getchar() != '\n' ) ; /* flush stdin up to and including '\n' */

    return s;
}




Try demo using strtok ...
(NEED a copy of your line that you parse BEFORE you parse it,
if you want to show that line later.)


int main()
{
    char word1[MAX_BUF_LEN], /* to find this word */
         word2[MAX_BUF_LEN], /* to find this word */
         filename[MAX_BUF_LEN]; /* to find if words in this file */

    char line[MAX_BUF_LEN], /* to hold a file line ... */
         line2[MAX_BUF_LEN]; /* to hold a copy of the above file line */

    int wordcount1 = 0, wordcount2 = 0, linecount = 0;

    FILE* fp;

    printf( "Enter the first word: " );
    fgets( word1, MAX_BUF_LEN, stdin );
    fixFgets( word1 );
    strToLower( word1 );

    printf( "Enter the second word: " );
    fgets( word2, MAX_BUF_LEN, stdin );
    fixFgets( word2 );
    strToLower( word2 );

    printf("Enter the name of the text file: ");
    fgets( filename, MAX_BUF_LEN, stdin );
    fixFgets( filename );

    fp = fopen( filename, "r" );

    while( fgets( line, MAX_BUF_LEN, fp  ) != NULL )
    {
        char c;

        /* note that there MAY be a '\n' before the final '\0' */

        char* p = strchr( line, '\n' );

        if( p ) *p = '\0'; /* trim off trailing '\n' IF it was there ... */
        else while( ( c = fgetc( fp )) != '\n' && c != EOF ) ; /* flush ... */

        strcpy( line2, line ); /* get a copy ... */

        strToLower( line );

        ++ linecount;

        p = strtok( line, " ." );
        while( p != NULL )
        {
            if( strcmp( word1, p ) == 0 )
            {
                ++ wordcount1;
                if( wordcount1 == 1 )
                    printf( "\nThe word '%s' first appears "
                            "in line %d which is:\n'%s'\n",
                            word1, linecount, line2 );
            }
            else if( strcmp( word2, p ) == 0 )
            {
                ++ wordcount2;
                if( wordcount2 == 1 )
                    printf("\nThe word '%s' first appears in "
                           "line %d which is:\n'%s'\n",
                           word2, linecount, line2 );
            }
            p = strtok( NULL, " ." );
        }
    }

    if( wordcount1 > 0 )
        printf( "\nThe word '%s' appears %d time(s) in the file.",
                word1, wordcount1 );
    else
        printf( "\nThe word '%s' does not appear in the file.", word1 );

    if( wordcount2 > 0 )
        printf( "\nThe word '%s' appears %d time(s) in the file.",
                word2, wordcount2 );
    else
        printf( "\nThe word '%s' does not appear in the file.", word2 );

    return 0;
}

Was This Post Helpful? 0
  • +
  • -

#5 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1102
  • View blog
  • Posts: 4,597
  • Joined: 09-June 09

Re: C program with FILES..it crashes

Posted 11 May 2013 - 02:51 AM

David why don't you go over and mow there lawn while your at it. :D

Quote

/my program keeps on crashing when its trying to do the if(wordcount1>0) and if(wordcount2>0);

The only thing in your if statement is a printf. Since you are printing C strings, it is likely that your are attempting to print a non null-terminating string and your getting a seg fault. Try stepping through your code with a debugger to make sure that your strings are null terminated.

This post has been edited by jjl: 11 May 2013 - 02:51 AM

Was This Post Helpful? 0
  • +
  • -

#6 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: C program with FILES..it crashes

Posted 11 May 2013 - 03:35 AM

View Postjjl, on 11 May 2013 - 05:51 AM, said:

David why don't you go over and mow there lawn while your at it. :D

Quote

/my program keeps on crashing when its trying to do the if(wordcount1>0) and if(wordcount2>0);

The only thing in your if statement is a printf. Since you are printing C strings, it is likely that your are attempting to print a non null-terminating string and your getting a seg fault. Try stepping through your code with a debugger to make sure that your strings are null terminated.



When I was an absolute beginner and asked a real expert coder, Randy Hyde, of HLA fame,

for some help with a beginning level program,

Randy sent me back a well designed and commented working program.

That really helped me and also really fast-tracked my learning ...

For Randy's gifts of well commented code,

with his clean logic flow,

and his well documented coding style,

I will always be grateful.

One way I try to show my gratitude to Randy, is by passing on what he gave me.

Hope this little explanation helps some ... :)

This post has been edited by David W: 11 May 2013 - 03:36 AM

Was This Post Helpful? 0
  • +
  • -

#7 DblAAssassin  Icon User is offline

  • D.I.C Regular

Reputation: 34
  • View blog
  • Posts: 261
  • Joined: 11-May 13

Re: C program with FILES..it crashes

Posted 11 May 2013 - 09:46 AM

This is how I was thought to make the "remove_newline" function.
void strip_newline(char *str, int size)
{
   int i;
   for (i=0;i<size;++i){
       if ( str[i] == '\n'){
            str[i] = '\0';
            return;
            }
       }
}


Was This Post Helpful? 0
  • +
  • -

#8 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: C program with FILES..it crashes

Posted 11 May 2013 - 11:42 AM

That works, when the the len of the input string all fits in the buffer ...
(but is inefficient, passing the size and then counting the size again ...
don't forget C strings are 0 terminated char arrays )

However,
if the input string does not all fit into the buffer,
the part that didn't fit is still there waiting to be read next,
( This happened for the case that there was NO '\n' char when you checked above, but ignored that case. )

So what to do with this left over chunk of bytes ...
that for all lines, except perhaps the last, still has the '\n' char at the end ? ( If last <file> line has no newline there, then check EOF as end flag )

Well ... one thing to do with it is to flush/scrap it ...
right up to and including the end newline char
( or EOF ... if was at the file end with no newline char at the end of that last line)

So look at this code, as an alternative ...

char* fixFgets( char* str, FILE** fin )
{
   int c, len = strlen( str );
   if( len )
   {
      if( str[len-1] == '\n' ) 
         str[len-1] = '\0';
      else  /* input str was too long for buf str */
         while( ( c = fgetc( *fin )) != '\n' && c != EOF ) ;  /* flush ... */
   }
   return str;
}


This post has been edited by David W: 11 May 2013 - 05:36 PM

Was This Post Helpful? 0
  • +
  • -

#9 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1102
  • View blog
  • Posts: 4,597
  • Joined: 09-June 09

Re: C program with FILES..it crashes

Posted 12 May 2013 - 07:25 PM

The problem is that you are using gets....don't use gets!(use fgets) gets is so dangerous that even gcc will warn you about using it. The reason why gets is not working with your code is that it does not insert the new line character into the string. So when you pass a string that was recieved via gets to your remove_newline function, you hit an infinite loop (which eventually segfaults when you increment i past the bounds of your string).

/*remove new line character from string obtained used fgets*/
void remove_newline(char s[], char t[]) { 
   int i = 0;
   while(s[i] != '\n'){ /* ALWAYS TRUE, WILL EVENTUALLY SEG FAULT*/
      t[i] = s[i];
      i++;
   }
   t[i] = '\0';
} 



Quote

When I was an absolute beginner and asked a real expert coder, Randy Hyde, of HLA fame,

for some help with a beginning level program,

Randy sent me back a well designed and commented working program.

That really helped me and also really fast-tracked my learning ...

For Randy's gifts of well commented code,

with his clean logic flow,

and his well documented coding style,

I will always be grateful.

One way I try to show my gratitude to Randy, is by passing on what he gave me.

Hope this little explanation helps some ...

Well that may have worked for you, however most users that post there questions on this form have been struggling with there code for hours, if not days. The biggest learning experience will come from them debugging and understanding there own code, not code that someone told them to use as an alternative.

This post has been edited by jjl: 12 May 2013 - 07:42 PM

Was This Post Helpful? 3
  • +
  • -

#10 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: C program with FILES..it crashes

Posted 13 May 2013 - 09:04 PM

Re: C program with FILES..it crashes #9

Posted June 12th, 2013, 10:25 PM

Quote

The problem is that you are using gets....
don't use gets!(use fgets) gets is so dangerous that even gcc
will warn you about using it. The reason why gets is not working
with your code is that it does not insert the new line character
into the string. So when you pass a string that was recieved via
gets to your remove_newline function, you hit an infinite loop
(which eventually segfaults when you increment i past the bounds
of your string).


/*remove new line character from string obtained used fgets*/
void remove_newline(char s[], char t[]) { 
   int i = 0;
   while(s[i] != '\n'){ /* ALWAYS TRUE, WILL EVENTUALLY SEG FAULT*/
      t[i] = s[i];
      i++;
   }
   t[i] = '\0';
}



But did you notice that 'lisa101' was *only* passing to

the remove_newline function ...

*** strings that were obtained by using fgets *** ?

So ... the comment that was added to lisa101's code above ...

/* ALWAYS TRUE, WILL EVENTUALLY SEG FAULT*/

is not entirely true here.

Please see the following, and my sincere thanks to you 'jjl' ...

for your encouragement to dig a little deeper here,

since using fgets correctly and trouble free

can be an unnecessarily big hurdle and stumbling block

for beginning C coders

i.e. until one sees how readily all the problems of using fgets can be
fixed with just a little added wrapper function code.


Like in the following example(s) ...

/* fixedFgets.h */ /* 2012-06-01 */ 

/* updated to also have dwUPDOWN strToUpper and strToLower on 2013-04-03 */

#ifndef FIXEDFGETS_H
#define FIXEDFGETS_H

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


#ifndef MAX_LINE_LEN
#define MAX_LINE_LEN 1023
#endif

#ifndef dwMYASSERT
#define dwMYASSERT
void myAssert( int condition, const char text[] )
{
    if( !condition )
    {
        fprintf(stderr, "%s\n", text );
        fputs( "Press 'Enter' to exit program ... ", stderr );
        getchar();
        exit(1);
    }
}
#endif

#ifndef dwNEWMEMORY
#define dwNEWMEMORY
char* newMem( int bytes )
{
    char* n = (char*) malloc( bytes ); /* cast for C++ compilers */
    myAssert( (n != NULL), "Error: malloc failed in 'newMem' ... " );
    return n;
}
#endif

#ifndef dwNEWCOPY
#define dwNEWCOPY
char* newCopy( const char* str )
{
    char* n = newMem( strlen(str) + 1 );
    strcpy( n, str );
    return n;
}
#endif

#ifndef dwTRIM
#define dwTRIM
char* trim( char* s )
{
    char *start = s, *end = s;
    while( *end ) ++end ;
    if( end == s ) return s; /* empty string */

    for( --end; s <= end && isspace(*end); --end ) ;
    end[1] = 0;

    while( isspace(*s) ) ++s;
    memmove( start, s, end+2-s ); /* 2 ... to copy terminal 0 */
    return start;
}
char* rtrim( char* s )
{
    char* end = s;
    while( *end ) ++end ;
    if( end == s ) return s; /* empty string */

    for( --end; s <= end && isspace(*end); --end ) ;
    end[1] = 0;
    return s;
}
char* ltrim( char* s )
{
    char *start = s, *end = s;
    while( *end ) ++end ;
    if( end == s ) return s; /* empty string */

    while( isspace(*s) ) ++s;
    memmove( start, s, end+1-s ); // 1 ... to copy terminal 0 //
    return start;
}
#endif

#ifndef dwUPDOWN
#define dwUPDOWN
char* strToUpper( char* str )
{
	char* p = str;
	while( *p != 0 ) { *p = toupper(*p); ++p; }
	return str;
}

char* strToLower( char* str )
{
	char* p = str;
	while( *p != 0 ) { *p = tolower(*p); ++p; }
	return str;
}
#endif



char* fixedFgets( char* s, size_t bufSize, FILE** fin )
{
    if( fgets( s, bufSize, *fin ) )
    {
        char *p = strchr( s, '\n' ), c ;
        if( p ) *p = 0; /* strip off '\n' at end ... IF it exists */
        else while( (c = fgetc( *fin )) != '\n'  &&  c != EOF ) ; /* flush... */
        return s;
    }
    else return NULL;
}

char* newFgets( FILE** fin )
{
    char buf[MAX_LINE_LEN+1];
    
    if( fgets( buf, sizeof(buf), *fin ) )
    {
        char *p = strchr( buf, '\n' ), c ;
        if( p ) *p = 0; /* strip off '\n' at end ... IF it exists */
        else while( (c = fgetc( *fin )) != '\n'  &&  c != EOF ) ; /* flush... */
        return newCopy( buf );
    }
    else return NULL;
}

#endif




Hi lisa101,

When I finally had some time to more closely examine your original code, I saw
your nice and simple algorithm to parse the words in a line, jump out at me,
(which I'm sorry to say I missed at the first look, because I too early jumped
to some impressions of your code ...
when I noticed your use of gets mixed in with using fgets ...

So, a BIG THANK-YOU to 'jjl' for the encouragement to look at your code closer.

Hope you are still with us lisa101, and are enjoying this ...

Even more, I hope you are learning from all this discussion back and forth.

Please excuse the 'rushed example code' to handle your problem a few days ago.
I didn't have the time then to study your code much ...
as 'jjl' has now graciously done for you.

I had hoped then, that my example(s) of 'fixing fgets' would point out for you ...
all the problems associated with using fgets.

I agree with 'jjl', that after working for a long long time, maybe days,
on a short piece of troublesome code, there is a special satisfaction of
getting that code working, even if it is only a partial fix.

However, as you are probably experiencing these day,
a student doesn't often have, 'at the present time',
very much time to ponder ... or to dally ... so then,
seeing an example of a working solution can be a great learning tool,
and will allow one to move forward.

And then, perhaps at a later time,
if that time ever comes,
when one can afford the luxury of looking back,
and most probably then,
with a lot more coding experience and examples behind,
that former 'big problem' seems much smaller and much more readily handled.

So a goal here for beginning programming students is,
to *as much as possible*,
reduce the ... 'too often way too big pain' ...
in the large learning curve for beginning programmers in C or C++

Programming should be... and can actually be fun :)

But remember the truth in this popular saying:

"No pain ... No gain!"

So it becomes the responsibility of the student to diligently study
any working carefully designed examples given here ...

to see ...
1. why they work ... and
2. what were the problems that they successfully overcame
3. the logic flow ...
4. the 'why' of the design factors

And to then ask questions if the student still can't
understand some parts of the example code,
even after considerable diligent study and research and testing out,
with various inputs and seeing and understanding the output,
with each particular test input.



Are you surprised now ... that ...

FILE input with fgets can be a little tricky ?

You knew that fgets KEEPS the newline char(s)
that mark the end of each file line
in its input buffer C string ...

BUT ... and yes, there are some important 'BUTS' HERE,

* the above is the case ... UNLESS *
1. the file line read with fgets was too large for buf
2. the last file line has NO newline char(s) at its end

The newline char(s) will *NOT* be there (in the input buf C string using fgets)
in either of these above TWO cases.


These two exception cases can be (sometimes) managed by ...

1. using an extra large input buffer C string (to prevent case 1. above)
2. checking firstly ... and then ensuring ...(i.e. add if needed)
that the last file line has the appropriate newline char(s) at end
(to prevent case 2 above)


But these problems with using fgets str input ...
can ALWAYS be managed by ...

3. writing code, as per my 'fixFgetsStr' function,
to handle BOTH CASES OF:
1. INPUT BUF NOT BEING BIG ENOUGH (if you can scrap the extra) AND
2. MISSING NEWLINE CHAR(S) AT END OF LINE


BUT NOTE:
IF (in your original program)
you had an input buffer C string ...
that was LARGE ENOUGH to hold ALL of EVERY file line (in your test file)
AND IF
that last file line HAD the appropriate newline char(s) at its end

Then ... your code would NOT have crashed

But ... aren't you glad that at least one of those conditions was NOT met,
in you testing ...
so that then ...
your running program crashed and that then led to all this discussion :)

Please take a look at this example (part fix) to your code,
and see the added comments ...
and note 'the old school style debug trick' used here
and compile/run your code with debug set to 1 and to 0
and with (too) small a buffer size
and with a file that has (and then doesn't have) newline char(s) at the end
of the last file line

Also... if both problematic conditions 1. and 2. above are met
with your code and test file ... using fgets
you might like to change the '\0' back to '\n' to see that your program
doesn't crash ... (but DON'T CODE THAT WAY.)


You may like to see the edits and comment in your slightly revised code below.

Shalom,

David


/* lisa101wordFind.c */

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

#define LBUF_LEN 512
#define WBUF_LEN 128 /* programmer must take responsibilty here to have EXTRA
                        large buffer if using gets, OR WILL OVERFLOW unchecked
                        BUT ...  why not here ... just use fgets every where ? */

#define debug 1 /* set to 0 to turn off */


/*
    convert word at s to lower case in new copy at t
    programmer must ensure t is large enough to hold s
*/
void word_tolower( char s[], char t[] )
{ 
   int i = 0;
   while( s[i] != '\0' )
   {
      t[i] = tolower( s[i] );
      i++;
   }

   t[i] = '\0';
}


/*
    copies C string s to t ( with '\n' char removed *IFF was there* )
    NOTE:  it won't be there in ...
           1. the case of a file line read with fgets, that was too large for buf
           2. the case of the last file line having NO newline char(s) at its end
    Note2: programmer must ensure t is large enough to hold s
*/
void remove_newline( char s[], char t[] ) 
{
   int i = 0;
#if debug
   static int count = 0;
#endif
   while( s[i] != '\0' ) /* you had .... while( s[i] != '\n' ) */
   {
        t[i] = s[i];

        if( t[i] == '\n' )
        {
#if debug
            printf( "%d, %s", ++count, s );
            getchar();
#endif
            break;
        }
        i++;
    }
    t[i] = '\0';
}



int main()
{
    char line[LBUF_LEN], line2[LBUF_LEN],
         filename[WBUF_LEN],
         word[WBUF_LEN],
         word1[WBUF_LEN], word2[WBUF_LEN],
         lword1[WBUF_LEN], lword2[WBUF_LEN];

    int i, j, wordcount1, wordcount2, linecount;

    FILE *fp;

    printf( "Enter the first word (less than max of %d char's) : ",
            WBUF_LEN-1 );
    gets( word1 );
    word_tolower( word1, lword1 );

    printf( "Enter the second word (less than max of %d char's) : ",
            WBUF_LEN-1 );
    gets( word2 );
    word_tolower( word2, lword2 );

    printf( "Enter the name of the text file (less than max of %d char's) : ",
            WBUF_LEN-1 );
    gets( filename );


    wordcount1 = wordcount2 = linecount = 0;
  
    fp = fopen( filename, "r" );
    if( fp )
    {
        /* can you see 'why' the edit here ? */
        while( fgets(line, LBUF_LEN, fp) /* !feof(fp) */ ) /* for each line */
        {
            linecount++;
#if debug
            /* some debugging code ...*/
            printf( "%d, %s", linecount, line );
#endif

            /* fgets(line, LBUF_LEN, fp); */ /* do you see 'why' the edit here */

            /* note that there *MAY* be a '\n' before the final '\0' */
            /* remove '\n' for printing of line2 *IFF* there */
            remove_newline( line, line2 ); 

            i = j = 0;

            while( line[i] != '\0' ) /* get each of the words on this line */
            {
                if( line[i] != ' ' && line[i] != '.'
                    && line[i] != '(' && line[i] != ')' && line[i] != '\n' )
                {
                   word[j] = tolower( line[i] );
                   j++;
                }
                else
                {
                    word[j] = '\0';
                    j = 0; /* now reset j to prepare for next word (in line) */

                    if( !strcmp( word, lword1 ))
                    {
                        wordcount1++;
                        if( wordcount1 == 1 )
                        {
                            printf( "The word '%s' first appears in line %d "
                            "which is:\n'%s'\n", word1, linecount, line2 );
                        }
                    }
                    else if( !strcmp(word, lword2 ))
                    {
                        wordcount2++;
                        if( wordcount2 == 1 )
                        {
                            printf( "The word '%s' first appears in line %d "
                            "which is:\n'%s'\n", word2, linecount, line2 );
                        }
                    }
                }

                ++i;

            }
        }

        if( wordcount1 )
            printf( "The word '%s' appears %d time(s) in the file.",
                    word1, wordcount1 );
        else
            printf( "The word '%s' does not appear in the file.", word1 );

        if( wordcount2 )
            printf( "\nThe word '%s' appears %d time(s) in the file.",
                    word2, wordcount2 );
        else
            printf( "\nThe word '%s' does not appear in the file.", word2 );
    }
    else
        printf( "\nThere was a problem opening file %s\n", filename );

    return 0;
}



This post has been edited by David W: 13 May 2013 - 09:36 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1