Search code examples
cstringcomparestrtokstrcmp

Using strcmp() on output of strtok() -C


I'm new to C, and I'm trying to write a program that takes two string literals, finds the longest word in the first, and compares it to the second string. If the second string (called "expected") is indeed equal to the first, it prints a success message, and if not, it prints the actual longest word, the expected string, and the original string.

There are many other posts on here with similar problems, but those boil down to an added \n or a missing \0; from what I understand, strtok() adds \0 and since I'm working with hard-coded literals, I'm sure there are no trailing line breaks, as is the case with reading input.

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

char* currentTok;
static const char* result;
static char* longestTok;

static int testsExecuted = 0;
static int testsFailed = 0;

void testLongestWord();
const char* longestWord();
int totalLength();
int charLength();

int main(int argc, char *argv[]) {
    printf("Testing typical cases, including punctuation\n");
    testLongestWord("the quick brown foxes jumped over the lazy dogs", "jumped");
    //There are other examples, some of which fail, and others don't, though I don't see a pattern

    printf("\nTotal number of tests executed: %d\n",testsExecuted);
    printf("Number of tests passed:         %d\n",(testsExecuted - testsFailed));
    printf("Number of tests failed:         %d\n",testsFailed);
}

//tests words, prints success/failure message
void testLongestWord(char* line, char* expected){
    result = longestWord(line, totalLength(line));
    if (strncmp(result, expected,charLength(expected)-1)||totalLength(expected)==0){//the problem spot
        printf("Passed: '%s' from '%s'\n",expected, line);
    } else {
        printf("FAILED: '%s' instead of '%s' from '%s'\n",result, expected, line);
        testsFailed++;
    }
    testsExecuted++;
}

//finds longest word in string
const char *longestWord(char* string, int size){
    char tempString[size+10];//extra room to be safe
    strcpy(tempString,string);
    currentTok = strtok(tempString,"=-#$?%!'' ");
    longestTok = "\0";
    while (currentTok != NULL){
        if (charLength(currentTok)>charLength(longestTok)){
            longestTok = currentTok;
        }
        currentTok = strtok(NULL,"=-#$?%!'' ");
    }

    return longestTok;
}

int totalLength(const char* string) {
    int counter = 0;

    while(*(string+counter)) {
        counter++;
    }
    return counter;
}

int charLength(const char* string) {
    int counter = 0;
    int numChars = 0;

    while(*(string+counter)) {
        if (isalpha(*(string+counter))){
            numChars++;
        }
        counter++;
    }
    return numChars;
}

The problem is that it returns:

FAILED: 'jumped' instead of 'jumped' from 'the quick brown foxes jumped over the lazy dogs'

Clearly, the strings are equal, and I've done other tests to make sure they're the same length, have \0... but still it fails.


Solution

  • You are calling strncmp() which returns zero on equal strings, but you are evaluating it in a boolean context where zero is false, so it falls to the else branch.

    Also, consider using strlen() to find out the length of a string.