为什么 strcasecmp() 不返回 0 尽管它在 C 程序中应该正确区分大小写?

问题描述

我的 check() 函数代码顶部)中的 strcasecmp 无法正常工作。当我运行代码时,它不会不区分大小写。我认为这与我比较的类型有关,但我还想不通...... PS:它来自 CS50 但我已经提交了问题,所以这里没有作弊 ;)

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

#include "dictionary.h"


// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;


// Number of buckets in hash table
const unsigned int N = 1000; //CHANGE THIS ACCORDING TO HASH ALGORITHM


// Hash table
node *table[N];

// used for size() to keep track of dictionary size
int dict_size = 0;


// Returns true if word is in dictionary (case-insensitive),else false
bool check(const char *word)
{

    //1: hash word to obtain hash value
    //2: access linked list at that index in hash table
    //cursor = first item of linked list

    node *cursor = table[hash(word)];



    //then move the cursor until it's NULL
    //use cursor (cursor = cursor->next) to traverse through linked list

    //true if word found

    while(cursor != NULL)
    {

        //has to be ZERO! strcasecmp returns numbers if the words differ,not true or false

        if (strcasecmp(cursor->word,word) == 0)
        {
            return true;
        }
        cursor = cursor->next;
    }



    //false if reached NULL and word has not been found

    return false;
}




//Hashes word to a number
//takes word as input
//outputs a number corresponding to which "bucket" (index in an array) to store the word
//Could do first letter,first two letters,MATH??? ---> SEARCH ONLINE AND GIVE THE SOURCE
unsigned int hash(const char *word)
{


    //make it deterministic
    //use SDBM Hash Function from source
    unsigned hashval;

    for (hashval = 0; *word != '\0'; word++)
    {
        hashval = *word + 31 * hashval;
    }
    return hashval % N;


    //SOURCE: https://stackoverflow.com/questions/7666509/hash-function-for-string
}




// Loads dictionary into memory,returning true if successful,else false
bool load(const char *dictionary)
{

    //1: open dict file
    FILE *dict = fopen(dictionary,"r");
    char expression[LENGTH + 1];

    //check for return value NULL
    if (dict == NULL)
    {
        printf("Could not open file!");
        return false;
    }


    //FOR EVERY WORD IN DICT!

    //2: read strings ("expression") from file one at a time
    //do until fscanf returns EOF
    while (fscanf(dict,"%s",expression) != EOF)
    {

        //count words (in global variable) to determine size of dict
        dict_size++;


        //3: create a new node for each word
        //use malloc to make new node
        //check for NULL
        //strcpy word into node
        node *new_node = malloc(sizeof(node));
        if (new_node == NULL)
        {
            printf("Not enough memory for malloc");
            return false;
        }

        strcpy(new_node->word,expression);
        new_node->next = NULL;


        //4: hash word to obtain a hash value
        //use hash function
        //this will return an index (alphabet-index)

        //5: insert node into hash table at that locatíon
        //index into hashtable to get linkedlist that you want to add word into
        //set pointers to correct order!!!
        //first point from new_node to node-number1 and then from head to new_node to not "lose" the list


        new_node->next = table[hash(expression)];
        table[hash(expression)] = new_node;
    }



    //first: allocate memory for new node
    // node *n = malloc(sizeof(node));
    // strcpy(n->word,"HELLO") --> change to different from hello
    // n->next = NULL

    //load all words from dict into a hash table
    //stop when node->next == NULL

    //array of linked lists (each of which represents an char (a,b,c,d,...))
    //need to use datatype "node"
        //needs hash function
        //takes word (e.g. "apple") and outputs,which is the starting char


    // return true if successfully loaded into memory

    fclose(dict);
    return true;
}

解决方法

编辑:我发现,我可以在散列函数中使用 tolower() 来解决问题。但老实说,我不知道为什么这现在有效......

unsigned int hash(const char *word)
{


    //make it deterministic
    //use Hash Function from source
    unsigned hashval;

    for (hashval = 0; *word != '\0'; word++)
    {
        hashval = tolower(*word) + 31 * hashval;
    }
    return hashval % N;


    //SOURCE: https://stackoverflow.com/questions/7666509/hash-function-for-string
}