Hello friends, I am having a problem writing a function to search for a string in an input file. I have successfully output the file with line numbers, which was the first step in the program, but now I am stuck on searching for a given string. After searching for the string I want to print the number of times it appears in the input file. As of right now all the function does is return a junk number. I have tried many different things and haven't gotten anything to work correctly.
Here is my code

#include <stdio.h>
#include <string.h>
#define MAX 1000
void find_string(char text[], char pattern[]);
int main()
{
    char pattern[] = "of"; //string to search for
    int counter = 0;
    static const char filename[] = "in.txt";        
    FILE *file = fopen(filename, "r");    
    if ( file != NULL )
    {
     char line [ MAX ]; 

      while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
      {
            ++counter;
            printf( "%d  ", counter);
            fputs ( line, stdout ); /* write the line */
      }
      printf( "\n\n");

      find_string(filename, pattern);
      fclose ( file );
   }
   else
   {
      perror ( filename ); 
   }
   
   char wait;
   scanf( "%c", &wait );
   return(0);
}

void find_string(char text[], char pattern[])
{
     int matches;
     static const char filename[] = "in.txt";    
     FILE *file = fopen(filename, "r");    
     if ( file != NULL )
     {
        char line [ MAX ]; 

        while ( fgets ( line, sizeof line, file ) != NULL ) 
        {
           if( line == pattern)
                    matches++;
        }
     printf("%d", matches);
     }
}

Thanks to anyone who takes the time to point me in the right direction.

I attached the input file as an attachment.
Thanks again for any help.

Recommended Answers

All 10 Replies

if( line == pattern)

That's a no-no, since line and pattern are strings and you can't compare arrays in that way.
Take a look at the string function strcmp() for that.
However, even if that would be correct, line is bound to have more characters read into, that the pattern, (unless fgets() by coincidence reads only the pattern).
Maybe the function strstr() would be more helpful.

You open the file in main() and read from it, then you open the same file in the function and read from it, you do not close it in the function, then close it in main. I'll say there's something odd, don't you think?

Yes Aia you are right that there are a few dumb mistakes in my code. ;)
I did some searching and found the following code using strstr.

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

#define SIZE 100

void search_string(char *);

int main(void)
{
	char array[SIZE];

	puts("Enter a string:");
	gets(array);
	search_string(array);

   char wait;
   scanf( "%c", &wait );
	return 0;
}

void search_string(char *array)
{
	char *ptr, *strptr, word[SIZE] = {""};
	int i = 0, j = 0;

	ptr = array;

	while (*ptr != '\0')
	{
		if (isspace(*ptr))
			break;
		word[i] = array[i];
		ptr++;
		i++;
	}
	strptr = array;
	
	while ((strptr =strstr(strptr, word)) != NULL)
	{
		strptr++;
		j++;
	}

	puts(array);
	printf("%s occured %d times in the string\n", word, j);
}

I have tried to apply this code to my porblem but have been unsuccessful. Here is what I tried.

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 1000
#define SIZE 100

void search_string(char *file);

int main()
{
    char pattern[] = "of";
    int counter = 0;
    const char filename[] = "in.txt";        
    FILE *file = fopen(filename, "r");    
    if ( file != NULL )
    {
     char line [ MAX ]; 

      while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
      {
            ++counter;
            printf( "%d  ", counter);
            fputs ( line, stdout ); /* write the line */
      }
      printf( "\n\n");

      search_string(file);
      fclose ( file );
   }
   else
   {
      perror ( filename ); 
   }
   
   char wait;
   scanf( "%c", &wait );
   return(0);
}


void search_string(char *file)
{
	char *ptr, *strptr, word[SIZE] = {"of"};
	int i = 0, j = 0;

	ptr = file;

	while (*ptr != '\0')
	{
		if (isspace(*ptr))
			break;
		word[i] = file[i];
		ptr++;
		i++;
	}
	strptr = file;
	
	while ((strptr = strstr(strptr, word)) != NULL)
	{
		strptr++;
		j++;
	}
	printf("%s occured %d times in the string\n", word, j);
}

However, when I run the code it outputs 0 as the number of times the word occurs.
I feel that by changing 'array' in the first code to 'file' in the second code I should have gotten the right answer because file, like array, is what was being searched for the string.
Does anyone see what I did wrong?

I passed this posting numerous times and I always wondered how do you define what your string is...i.e. can your string span more than one line in your text file, can your string overlap, can it overlap many times...with these questions bouncing around in my head the only way I can find to interrogate a text file is to start with the first character and check the preceding characters to see if you have a match, if you do increment count if not move to the next char and check the preceding characters....

Note with this method you have to disregard newline characters

If an alternate approach helps at all: strstr in this case, since it returns "a pointer to the located string (or null ptr if it isn't found)" you can (hypothetically) read your entire file into an array, then use strstr to find the first occurrence of whatever you're searching for. While you still find occurrences, keep calling strstr. The trick is to use pointer arithmetic to figure out where in the array to start searching on each iteration of your while loop. So basically: (pseudocode)

while(ptr != null){
- ptr = strstr(arrayposition, strToLookFor);
- arrayposition = now do some pointer arithmetic to find out the place in the array where you just saw the last substring.
}

(edit) after re-reading your code, it looks like you did already realize this. But maybe my approach will be a slightly easier approach.

I got my function to work somewhat but it only prints the number of occurrences of the first word of the last line in the last line only. I just want to get the program to search all lines for the first word of the txt file.
Here is the revised code

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 1000
#define SIZE 100

void search_string(char *file);

int main()
{
    int counter = 0;
    const char filename[] = "in.txt";        
    FILE *file = fopen(filename, "r");    
    if ( file != NULL )
    {
     char line [ MAX ]; 

      while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
      {
            ++counter;
            printf( "%d  ", counter);
            fputs ( line, stdout ); /* write the line */
      }
      printf( "\n\n");
      search_string(line);
      fclose ( file );
   }
   else
   {
      perror ( filename ); 
   }
   
   char wait;
   scanf( "%c", &wait );
   return(0);
}


void search_string(char *file)
{
	char *ptr, *strptr, word[SIZE] = {" "};
	int i = 0, j = 0;

	ptr = file;

	while (*ptr != '\0')
	{
		if (isspace(*ptr))
			break;
		word[i] = file[i];
		ptr++;
		i++;
	}
	strptr = file;
	
	while ((strptr = strstr(strptr, word)) != NULL)
	{
		strptr++;
		j++;
	}

	printf("%s occured %d times in the string\n", word, j);
}

If anyone has any ideas on how to implement my function to meet my needs I'd be very grateful. Thanks

I got my function to work somewhat but it only prints the number of occurrences of the first word of the last line in the last line only.

because you are calling the function search_string(line); after the statement

while ( fgets ( line, sizeof line, file ) != NULL )
{
        :
        :
}

by the time it comes out of while line is having last line of the file.


I just want to get the program to search all lines for the first word of the txt file.

probably you want to search for the first word(Secret) in all line
you can modify so easily.

i have just edited your code, i dont completly understand your requirement , but this works fine for all the lines.
you can modify as per your Req:

Here is the revised code

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 1000
#define SIZE 100
void search_string(char *file);

int main()
{
    int counter = 0;
    const char filename[] = "in.txt";        
    FILE *file = fopen(filename, "r");    
    if ( file != NULL )
    {
     char line [ MAX ]; 

      while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
      {
            ++counter;
            printf( "%d  ", counter);
            fputs ( line, stdout ); /* write the line */
            search_string(line);   
   }
      printf( "\n\n");
      //search_string(line); 
      fclose ( file );
   }
   else
   {
      perror ( filename ); 
   }
   
   char wait;
   scanf( "%c", &wait );
   return(0);
}


void search_string(char *file)
{
	char *ptr, *strptr, word[SIZE] = {" "};
	int i = 0, j = 0;
                int spc =0;

	ptr = file;

	while (*ptr != '\0')
	{
		if (isspace(*ptr) && spc == 0)
                                 {
                                    spc  = 0;
                                  }
 		if(spc != 0 && isspace(*ptr))
                                                break;
		if(isalnum(*ptr))
                                {     
                                    spc =1;
                                    word[i] = *ptr ; // file[i];
          /* here file[i] is blank , is a problem do you really want that*/      
                                   i++;
	                }
                    ptr++;
                 }
              word[i]='\0';
	strptr = file;
	
	while ((strptr = strstr(strptr, word)) != NULL)
	{
		strptr++;
		j++;
	}

	printf("%s occured %d times in the string\n", word, j);
}

If anyone has any ideas on how to implement my function to meet my needs I'd be very grateful. Thanks

I Hope this does ...

probably you want to search for the first word(Secret) in all line
you can modify so easily.

Thanks for the reply. That however is not really what I'm looking for. Let me clarify. I want to search all the lines for the first word in the file. The code you supplied counts the first word of each line in that specific line. I have tried putting the functrion call in the while loop prior to your post and then just moved it back out when I posted. The above quote is actually what I'm looking for. I have tried to edit the code but have been unsuccessful. Would you mind giving me some more advice? Thanks.

i hope this is what you want ..

i just edited , but some unneccessary statements/ variable are present that will not harm our prgram.

#include<stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 1000
#define SIZE 100
void search_string(char *file, char *pat);

int main()
{
      int counter = 0;
      int i=0;
     char ch;
     const char filename[] = "in.txt";
     char pat[50];
    FILE *file = fopen(filename, "r");
    if ( file != NULL )
    {
     char line [ MAX ];
     while(isspace(ch=fgetc(file))) ;
     pat[i++] = ch;
     while(!(isspace(ch=fgetc(file))))
     pat[i++] = ch;
     pat[i] = '\0';
     rewind(file);
     while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
     {
            ++counter;
            printf( "%d  ", counter);
            fputs ( line, stdout ); /* write the line */
            search_string(line,pat);
   }
      printf( "\n\n");
      //search_string(line);
      fclose ( file );
   }
   else
   {
      perror ( filename );
   }

   char wait;
   scanf( "%c", &wait );
   return(0);
}
void search_string(char *file, char *pat)
{
        char *ptr, *strptr, word[SIZE] = {" "};
        int i = 0, j = 0;
        int spc =0;
           /*
        while (*ptr != '\0')
        {
                if (isspace(*ptr) && spc == 0)
                                 {
                                    spc  = 0;
                                         }
                if(spc != 0 && isspace(*ptr))
                                                break;
                if(isalnum(*ptr))
                                {
                                    spc =1;
                                    word[i] = *ptr ; // file[i];
        / / here file[i] is blank , is a problem do you really want that
                                   i++;
                        }
                    ptr++;
                 }
              word[i]='\0';
             */

        strptr = file;
        while ((strptr = strstr(strptr, pat)) != NULL)
        {
                strptr++;
                j++;
        }
        printf("%s occured %d times in the string\n", pat, j);
}

I have tried to edit the code but have been unsuccessful. Would you mind giving me some more advice? Thanks.

i hope this time i am Ryt.

commented: Thanks for the help. +1

Thank you very much, that was very helpful.

although this thread has been marked solved, but I want to tell some of my ideas, hope it can be help to u.

We can suppose a pane which is as long as the pattern.
first, the pointer of the pane and the file are the same, so we can use the "strcmp" function to mesure them, then the pointer of pane slow move(is the pointer++).
In this way, we can get the times now!
Am I right?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.