1

I am trying a program in c to read a text file that contains array of characters or a string and find the number of occurrences of the substring called "GLROX" and say sequence found when it is found. And the "inputGLORX.txt" contains following string inside it.

GLAAAROBBBBBBXGLROXGLROXGLROXGLROXGLCCCCCCCCCCCCCCROXGGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROX

But i am getting wierd results. It would be great if some expert in C-programming helps me to solve this and thanks in advance.

#include <stdio.h>
#include <conio.h>
#include <string.h>
#define NUMBER_OF_STRINGS 40
#define MAX_STRING_SIZE 7
void seqFound()
{
    printf("Sequence Found\n");
}

int main()
{
    FILE *fp;
    char buff[1000];
    char strptrArr[NUMBER_OF_STRINGS] [MAX_STRING_SIZE];
    const char *search = "GLROX";
    fp = fopen("D:/CandC++/inputGLORX.txt", "r");

    if(fp==NULL)
        printf("It is a null pointer");

    while(!feof(fp))
    {
      //fscanf(fp, "%s", buff);
      fgets(buff, 1000,fp);
    }

    int len = strlen(buff);
    printf("length is %d\n",len);
    int count = 0;
    char *store;

    while(store = strstr(buff, search))
    {
       printf("substring is %s \n",store);
       count++;
       search++;
    }

    printf("count is %d\n",count);
    while (count!=0) {
        seqFound();
        count--;
    }
    return 0;
}
4
  • 3
    Two problems: First of all don't do while (!feof(fp)); Secondly if the file contains only a single line then your loop might not work as expected anyway, and if there's multiple lines in the file then it will probably not work as you expect either. I suggest you spend some time to learn how to use a debugger so you can step through the code statement by statement, as that should help you understand what's going on. Commented Sep 27, 2019 at 6:27
  • As said by @Someprogrammerdude, you should spend a little time in debugging. And you will be able to understand the issue with your code. You can use gdb or gdbgui for debugging. Commented Sep 27, 2019 at 6:35
  • 1
    By incrementing search, you reduce the length of the string you look for, omitting first G, then L, then O, then R, then X, and then getting into serious trouble. You should be changing the data you search, not the string you search for. Commented Sep 27, 2019 at 6:55
  • @Someprogrammerdude "if the file contains only a single line then your loop might not work as expected anyway, and if there's multiple lines in the file then it will probably not work as you expect either." :D Commented Sep 27, 2019 at 7:01

2 Answers 2

1

As said in the comment, their are at least 2 problems in the code: your fgets will only fetch the last line (if it fetch one at all ? In any case, this is not what you want), and you are incrementing the search string instead of the buff string.

Something like this should fix most of your problems, as long as no lines in your file are longer than 999 characters. This will not work properly if you use the \n or NULL characters in your search string.

int count = 0;
while (fgets(buff, 1000, fp) != NULL)
{
    char *temp = buff;
    while ((temp = strstr(temp, search)))
    {
        printf("%d. %s\n", count + 1, temp);
        count++;
        temp++;
    }
}

Here is a main for testing. I used argv to provide the input.txt and the search string.

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

int main(int argc, char **argv)
{
    FILE    *fp;
    char    buff[1000];
    char    *search;

    if (argc < 3)
        return (-1);
    search = argv[2];
    if (search[0] == '\0')
        return (-1);
    if ((fp = fopen(argv[1], "r")) == NULL)
        return (-1);
    int count = 0;
    while (fgets(buff, 1000, fp) != NULL)
    {
        char *temp = buff;
        while ((temp = strstr(temp, search)))
        {
            printf("%d. %s\n", count + 1, temp);
            count++;
            temp++;
        }
    }
    printf("Match found: %d\n", count);
    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

1

The way you search in buff is wrong, i.e. this code:

while(store = strstr(buff, search))
{
   printf("substring is %s \n",store);
   count++;
   search++;  // <------- ups
}

When you have a hit, you change search, i.e. the string you are looking for. That's not what you want. The search string (aka the needle) shall be the same all the time. Instead you want to move forward in the buffer buff so that you can search in the remainder of the buffer.

That could be something like:

int main()
{

  const char* buff = "GLAAAROBBBBBBXGLROXGLROXGLROXGLROXGLCCCCCCCCCCCCCCROXGGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROX";

  const char* search = "GLROX";
  const char* remBuff = buff;    // Pointer to the remainder of buff
                                 // Initialized to be the whole buffer
  const char* hit;
  int cnt = 0;
  while((hit = strstr(remBuff, search)))  // Search in the remainder of buff
  {
    ++cnt;
    remBuff = hit + 1;    // Update the remainder pointer so it points just 1 char
                          // after the current hit
  }
  printf("Found substring %d times\n", cnt);
  return 0;
}

Output:

Found substring 15 times

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.