1

I hate to ask a "what is wrong here?" question, but I'm working through the Head First C book and I came across an issue while attempting to compile an example which I took directly from the book. The aim of the code is simply to take input from the user and search the "Track List" (the strings in the track array) for any copy of the user's exact input. Since the code is taken directly from the book, it should compile and work perfectly with no issues. However, it is not recognizing when the input is a part of any of the strings. All of my own fruitless attempts to determine the source of the problem seem to point to the if state where the strstr function is used- but it's not overly complicated, and I don't see the issue. Here is the code:

    #include <stdio.h>
    #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 for 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;
    }
obro39
  • 11
  • 3
  • Have you stepped through this code in a debugger? Note: Convention has it you pass in `char*` not `char[]`. – tadman Aug 22 '18 at 21:59
  • @user3121023 I believe you can make it an answer. It's just that using `strcspn` for this seems to be an overkill... – Eugene Sh. Aug 22 '18 at 22:02
  • @user3121023- Can you elaborate somewhat? Based on what I found trying different things, this makes sense. I'm just not sure where the trailing newline comes from, and exactly what kind of syntax is used to resolve that issue. Is it convention to remove it the way you said, or is there a better way to accomplish the same result by changing other parts of the code? Thanks! – obro39 Aug 22 '18 at 22:07
  • @user3121023 Maybe not, you know... you still need to calculate the length to get the last character. – Eugene Sh. Aug 22 '18 at 22:08
  • @obro From [`man fgets`](https://linux.die.net/man/3/fgets): *..Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer...* – Eugene Sh. Aug 22 '18 at 22:09
  • @EugeneSh. So that is to say that when a user presses "enter" to indicate that the data is to be entered, it is stored as a "\n" newline character? Any ideas as to why the book seems to have ignored this, like differences with past versions or different compilers/OS/etc? – obro39 Aug 22 '18 at 22:13
  • 1
    @obro39 The code may have used `gets` originally, and somebody changed it to `fgets` without bothering to retest. `gets` was removed from the language in 2011. – user3386109 Aug 22 '18 at 22:23
  • @user3386109 so just to make sure I understand, the fix works by using strcspn to find the newline and replacing it with a null character, thereby solving the substring recognition issue? – obro39 Aug 23 '18 at 00:04
  • @EugeneSh. The "`strcspn()` technique" — `buffer[strcspn(buffer, "\n")] = '\0';` — has advantages over most alternatives because it works correctly when there is no newline in the buffer, or the buffer is empty. Tests with `strlen()` have to check for empty strings, and whether there's a newline at the end. Even using `strchr()` means you have to test whether you got a null pointer back. – Jonathan Leffler Aug 23 '18 at 00:32
  • You should check the return value from `fgets()`, but it probably isn't failing. You should print your input when you're not sure what it contains, making sure it is easy to spot some common problems, like embedded newlines or carriage returns. Consider: `printf("Searching for: [[%s]]\n", search_for);` after the call to `fgets()` and before the call to `find_track()`. The output will show the pair of `]]` brackets on the second line because the track name will contain a newline, because you hit 'return' when you finished typing the line (unless the input was so long it didn't fit). – Jonathan Leffler Aug 23 '18 at 00:39
  • @JonathanLeffler the trailing newline seems to have been an issue- there is a very good answer to another question about removing trailing newlines and now that I realize that was the problem it was an easy fix and a good thing to note for later. Thanks! – obro39 Aug 23 '18 at 00:42

0 Answers0