KOB
KOB

Reputation: 4545

Two similar loops - One works perfectly, the other doesn't

The following function is part of my program. The purpose of this function is to scan through a large text file and count the number of occurences (NameAppearences) of the names read from another file. The names read from the second file are stored in an array declared globally as char **Names. The following version of the function works as expected when it counts the number of occurences of Names[0]:

void SearchForNames()
{
    char LineOfText[85];
    char *TempName;
    char word[15];

    while(fgets(LineOfText, sizeof(LineOfText), fpn))
    {

        strncpy(word, Names[0], strlen(Names[0]) - 1);
        TempName = strstr(LineOfText, word);
        if(TempName != NULL)
        {
            NameAppearances++;
        }

    }
    printf("%d", NameAppearances);
}

However, if I alter this while loop to include a nested for loop in order to count the number of occurences of all of the names (Names[0] to Names[NumOfNames], it prints a value of 0 for NameAppearances:

while(fgets(LineOfText, sizeof(LineOfText), fpn))
{
    for(x=0; x<NumOfNames; x++)
    {
        strncpy(word, Names[x], strlen(Names[x]) - 1);
        TempName = strstr(LineOfText, word);
        if(TempName != NULL)
        {
            NameAppearances++;
        }
    }
}
printf("%d", NameAppearances);

I do not understand why this slight change in the loop causes it to work incorrectly.

Upvotes: 0

Views: 97

Answers (1)

chux
chux

Reputation: 153517

strncpy(word, Names[0], strlen(Names[0]) - 1); TempName = strstr(LineOfText, word); is undefined behavior.

word has no null character termination yet is used as string in strstr().


[Edit]

The following for string manipulation is bad. It leaves word with a copy of Names[0] except for a missing '\0'.

strncpy(word, Names[0], strlen(Names[0]) - 1);  // bad code

Instead to prevent buffer over-run use

word[0] = 0;
strncat(word, Names[0], sizeof word - 1);

[Edit 2]

Based on your other posts, insure your list of names have their '\n' removed.

    LineOfText[strcspn(LineOfText, "\n")] = 0;
    Names[x] = strdup(LineOfText);

Upvotes: 1

Related Questions