0

I'm new to C pointers and I'm trying to write a program similar to a high level programming language's String.IndexOf() function.

Based on String.indexOf function in C, I've got it working:

int main() {
    int index;
    char* source = "test string";
    char* found = strstr( source, "in" );
    if (found != NULL) {
        index = found - source;
    }

    printf("%d\n", index); // prints 8.
    return 0;
}

But when I try to use this as a function, I always get 0. (For example, "Hello World" for the first string then "World" will print "0" and not the expected value "6").

Basically, the first line from stdin is the "source" (or "haystack") string and the following lines will be the "needle".

// includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// globals
char master[120];

// returns the index of the substring
int substr(char* needle) {

    int index;
    char* found = strstr( master, needle );
    if (found != NULL) {
        index = found - needle;
    }

    printf("%d\n", index);
    return index;

}

int main() {
    char input[120];
    int timesCalled = 0;

    while(fgets(input, 120, stdin)) {
        timesCalled++;
        if (timesCalled == 1) {
            strcpy(master, input);
        } else {
            substr(input);
        }
    }

    if (timesCalled == 0) {
        fprintf(stderr, "Master String is empty");
        return 1;
    }

    return 0;
}

What's going on here? Does the pointer of "master" change when it's set as a global variable? Does the pointer of "input" change when it's passed as a parameter? Why does it work in the procedural version?

Any input is appreciated.

EDIT!

I've changed the line strcpy(input, master) to strcpy(master, input) and I still get the same result!

Community
  • 1
  • 1
chakeda
  • 1,551
  • 1
  • 18
  • 40
  • 1
    The code `fgets` a line into `input`. Then it `strcpy` the (yet uninitialized) `master` *over* `input`. What do you expect to happen? – dxiv Sep 25 '16 at 05:01
  • @dxiv Please see my edit - I've swapped `input` and `master` and I still get the same output. – chakeda Sep 25 '16 at 05:10

2 Answers2

1

Problem 1

You are passing the arguments to strcpy in the wrong order.

It needs to be:

strcpy(master, input);

The first argument is the destination and the second argument is the source.

Problem 2

Also, you are not finding needle in the haystack since fgets() reads the newline character also. You'll need to remove the newline before trying to search.

Problem 3

You are using the wrong pointer to compute index in substr.

  index = found - needle;

needs to be

  index = found - master;

Problem 4

You need to initialize index to something. Otherwise, it returns an uninitialized value when needle is not found in the haystack.

int substr(char* needle) {

    int index = -1; // Make the return value negative when needle is not found

    char* found = strstr( master, needle );
    if (found != NULL) {
        index = found - master;
    }

    printf("%d\n", index);
    return index;
}

A fixed up program

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

// globals
char master[120];

// returns the index of the substring
int substr(char* needle) {

   int index = -1;
   char* found = strstr( master, needle );
   if (found != NULL) {
      index = found - master;
   }

   printf("%d\n", index);
   return index;
}

void removeNewline(char* input)
{
   size_t len = strlen(input);
   if ( input[len-1] == '\n' )
   {
      input[len-1] = '\0';
   }
   else
   {
      printf("No newline found\n");
   }
}

int main() {
   char input[120];
   int timesCalled = 0;

   while(fgets(input, 120, stdin)) {
      removeNewline(input);
      timesCalled++;
      if (timesCalled == 1) {
         strcpy(master, input);
      } else {
         substr(input);
      }
   }

   if (timesCalled == 0) {
      fprintf(stderr, "Master String is empty");
      return 1;
   }

   return 0;
}

Input:

test string
in
es

Output:

8
1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • please see my edit - I've swapped `master` and `input` and I get the same output. What could cause this? – chakeda Sep 25 '16 at 05:09
  • Thank you for the very solid answer solving all of my issues. I've noticed I had a few problems when I ran the program with problem 3 fixed, but the removeNewline() fixed it up! – chakeda Sep 25 '16 at 05:34
1

Since you want the index in string master, what you need to do instead of

if (found != NULL) {
    index = found - needle;
}

is to replace index = found - needle with index = found - master.

iceeggocean
  • 174
  • 7
  • You are my savior! I have transcripted the linked question's solution incorrectly in my functional solution. I've definitely overthunk and looked over the little things. – chakeda Sep 25 '16 at 05:14