954,116 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

find string in file

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.

Attachments in.txt (0.51KB)
Grn Xtrm
Posting Pro in Training
495 posts since Nov 2008
Reputation Points: 100
Solved Threads: 48
 
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?

Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 

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?

Grn Xtrm
Posting Pro in Training
495 posts since Nov 2008
Reputation Points: 100
Solved Threads: 48
 

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

gerard4143
Nearly a Posting Maven
2,272 posts since Jan 2008
Reputation Points: 512
Solved Threads: 387
 

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.

BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
 

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

Grn Xtrm
Posting Pro in Training
495 posts since Nov 2008
Reputation Points: 100
Solved Threads: 48
 
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 ...

Iam3R
Junior Poster
110 posts since Oct 2009
Reputation Points: 34
Solved Threads: 4
 
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.

Grn Xtrm
Posting Pro in Training
495 posts since Nov 2008
Reputation Points: 100
Solved Threads: 48
 

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.

Iam3R
Junior Poster
110 posts since Oct 2009
Reputation Points: 34
Solved Threads: 4
 

Thank you very much, that was very helpful.

Grn Xtrm
Posting Pro in Training
495 posts since Nov 2008
Reputation Points: 100
Solved Threads: 48
 

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?

Tajon Wong
Newbie Poster
6 posts since Nov 2009
Reputation Points: 10
Solved Threads: 0
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You