0

I am trying to compile this program

#include <string.h>
char tracks[][80] = {
"I left my heart in Harvard Med School",
"Newark, Newark - a wonderful town",
"Dancing with a Dork",
"From here to maternity",
"The girl from Iwo Jima",
};
void find_track(char search_for[])
{
int i;
for (i = 0; i < 5; i++) {
if (strstr(tracks[i], search_for))
printf("Track %i: '%s'\n", i, tracks[i]);
}
}
int main()
{
char search_for[80];
printf("Search for: ");
fgets(search_for, 80, stdin);
find_track(search_for);
return 0;
}

The expected output after using input "town" is Track 1: 'Newark, Newark - a wonderful town' I am running it in CodeBlocks IDE and I get no output. The program exits. Using strategically placed printf statements it seems that strstr(tracks[i], search_for) is returning null. I am not sure why.

john
  • 113
  • 1
  • 6
  • 3
    Do basic debugging. Use a debugger to step through the code line by line. Read the [`fgets` man page](https://linux.die.net/man/3/fgets). Examine the contents of the `search_for` variable. – kaylum Mar 08 '21 at 20:41
  • I used printf comments, it seems to be skipping the if statement. – john Mar 08 '21 at 20:43
  • 3
    Did you do the other things? Reading the manual will tell you something very important that `fgets` does - it stores the newline at the end of the string. – kaylum Mar 08 '21 at 20:44
  • 2
    Use `search_for[strcspn(search_for, "\n")] = '\0';` to zap the newline at the end of the string. Printing the data with proper markers would reveal the problem. For example: `fprintf(stderr, "Search for [[%s]]\n", seach_for);` would show a newline before the `]]`, indicating the problem. The markers help spot issues with CR (carriage return) characters in the input, etc. – Jonathan Leffler Mar 08 '21 at 20:50
  • @JonathanLeffler adding that code ``search_for[strcspn(search_for, "\n")] = '\0';`` seems to do the trick. So you are replacing new line with the null character? – john Mar 08 '21 at 20:53
  • It looks like when I enter ``town`` and press Enter, fgets sees ``'t' 'o' 'w' 'n' '\n' '\0'`` . – john Mar 08 '21 at 20:58
  • Correct — terminating the string instead of including the newline. The advantage of using `strcspn()` is that you don't have to worry about whether there is a newline or not; it will zap the terminal null byte with another null byte if there is no newline. Most of the alternatives involve conditional code. OTOH, `strcspn()` is not necessarily the fastest way to do it. See [Why the `gets()` function is too dangerous to be used — ever!](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used) for more details on newline zapping. – Jonathan Leffler Mar 08 '21 at 21:00
  • So you are replacing ``'t' 'o' 'w' 'n' '\n' '\0'`` with ``'t' 'o' 'w' 'n' '\0' '\0'`` . Is there anything wrong with having two consecutive null terminating bytes, as far as using ``strstr() `` function – john Mar 08 '21 at 21:04
  • 1
    Nope. The first null byte terminates the string; string functions like `strstr()` (`strlen()`, `strcpy()`, etc) won't ever look at the second one. – Jonathan Leffler Mar 08 '21 at 21:04

0 Answers0