C-发出了解数据分配和未签名INT的方面



我有一个作业,要求我通过在某些给定代码中实现一些函数来编写拼写检查器。由于某些语法错误,我无法编译。

首先是:

speller.c:291:19: error: comparison of array 'trav_ptr->word' not equal to a null
      pointer is always true [-Werror,-Wtautological-pointer-compare]
    if (trav_ptr->word!=NULL)

和:

speller.c:293:13: error: cannot increment value of type 'unsigned int (void)'
        size++;

来自此功能:

void count(trie *root_ptr)
{
    trie *trav_ptr = root_ptr;
    if (trav_ptr->word!=NULL)
    {
        size++;
    }
    for (int n = 0; n<26; n++)
    {
        if (trav_ptr->paths[n]!=NULL)
        {
            trav_ptr=trav_ptr->paths[n];
            count(trav_ptr);
        }
    }
}

我相信我的问题在于了解Malloc的工作原理。当malloc trie trie

malloc
typedef struct trie
{
    char word[MAXCHAR];
    struct trie *paths[26];
}
trie;

我的结构的char场不是空的吗?由于我还没有填充任何东西。

至于另一个错误,我相信我不能增加unsigned int大小(在全球宣布),因为我没有初始化它,但是我不确定初始化它是否会弄乱给我的代码。

这是整个程序:

/**
 * Implements a spell-checker.
 */
#include <ctype.h>
#include <stdio.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <stdbool.h>
#include <stdlib.h>
#include <cs50.h>
#include <string.h>
#undef calculate
#undef getrusage
#define MAXCHAR 45
// default dictionary
#define DICTIONARY "dictionaries/large"
typedef struct trie
{
    char word[MAXCHAR];
    struct trie *paths[26];
}
trie;
double calculate(const struct rusage *b, const struct rusage *a);
#define LENGTH 45
bool check(const char *word, trie *root_ptr);
bool load(const char *dictionary, trie *root_ptr);
unsigned int size(trie *root_ptr);
bool unload(void);
void count (trie *root_ptr);

int main(int argc, char *argv[])
{
    // check for correct number of args
    if (argc != 2 && argc != 3)
    {
        printf("Usage: speller [dictionary] textn");
        return 1;
    }
    // structs for timing data
    struct rusage before, after;
    // benchmarks
    double time_load = 0.0, time_check = 0.0, time_size = 0.0, time_unload = 0.0;
    // determine dictionary to use
    char* dictionary = (argc == 3) ? argv[1] : DICTIONARY;
    // load dictionary
    trie *root = NULL;
    trie *root_ptr = root;
    getrusage(RUSAGE_SELF, &before);
    bool loaded = load(dictionary, root_ptr);
    getrusage(RUSAGE_SELF, &after);
    // abort if dictionary not loaded
    if (!loaded)
    {
        printf("Could not load %s.n", dictionary);
        return 1;
    }
    // calculate time to load dictionary
    time_load = calculate(&before, &after);
    // try to open text
    char *text = (argc == 3) ? argv[2] : argv[1];
    FILE *fp = fopen(text, "r");
    if (fp == NULL)
    {
        printf("Could not open %s.n", text);
        unload();
        return 1;
    }
    // prepare to report misspellings
    printf("nMISSPELLED WORDSnn");
    // prepare to spell-check
    int index = 0, misspellings = 0, words = 0;
    char word[LENGTH+1];
    // spell-check each word in text
    for (int c = fgetc(fp); c != EOF; c = fgetc(fp))
    {
        // allow only alphabetical characters and apostrophes
        if (isalpha(c) || (c == ''' && index > 0))
        {
            // append character to word
            word[index] = c;
            index++;
            // ignore alphabetical strings too long to be words
            if (index > LENGTH)
            {
                // consume remainder of alphabetical string
                while ((c = fgetc(fp)) != EOF && isalpha(c));
                // prepare for new word
                index = 0;
            }
        }
        // ignore words with numbers (like MS Word can)
        else if (isdigit(c))
        {
            // consume remainder of alphanumeric string
            while ((c = fgetc(fp)) != EOF && isalnum(c));
            // prepare for new word
            index = 0;
        }
        // we must have found a whole word
        else if (index > 0)
        {
            // terminate current word
            word[index] = '';
            // update counter
            words++;
            // check word's spelling
            getrusage(RUSAGE_SELF, &before);
            bool misspelled = !check(word, root_ptr);
            getrusage(RUSAGE_SELF, &after);
            // update benchmark
            time_check += calculate(&before, &after);
            // print word if misspelled
            if (misspelled)
            {
                printf("%sn", word);
                misspellings++;
            }
            // prepare for next word
            index = 0;
        }
    }
    // check whether there was an error
    if (ferror(fp))
    {
        fclose(fp);
        printf("Error reading %s.n", text);
        unload();
        return 1;
    }
    // close text
    fclose(fp);
    // determine dictionary's size
    getrusage(RUSAGE_SELF, &before);
    unsigned int n = size(root_ptr);
    getrusage(RUSAGE_SELF, &after);
    // calculate time to determine dictionary's size
    time_size = calculate(&before, &after);
    // unload dictionary
    getrusage(RUSAGE_SELF, &before);
    bool unloaded = unload();
    getrusage(RUSAGE_SELF, &after);
    // abort if dictionary not unloaded
    if (!unloaded)
    {
        printf("Could not unload %s.n", dictionary);
        return 1;
    }
    // calculate time to unload dictionary
    time_unload = calculate(&before, &after);
    // report benchmarks
    printf("nWORDS MISSPELLED:     %dn", misspellings);
    printf("WORDS IN DICTIONARY:  %dn", n);
    printf("WORDS IN TEXT:        %dn", words);
    printf("TIME IN load:         %.2fn", time_load);
    printf("TIME IN check:        %.2fn", time_check);
    printf("TIME IN size:         %.2fn", time_size);
    printf("TIME IN unload:       %.2fn", time_unload);
    printf("TIME IN TOTAL:        %.2fnn",
     time_load + time_check + time_size + time_unload);
    // that's all folks
    return 0;
}

/**
 * Returns number of seconds between b and a.
 */
double calculate(const struct rusage *b, const struct rusage *a)
{
    if (b == NULL || a == NULL)
    {
        return 0.0;
    }
    else
    {
        return ((((a->ru_utime.tv_sec * 1000000 + a->ru_utime.tv_usec) -
                 (b->ru_utime.tv_sec * 1000000 + b->ru_utime.tv_usec)) +
                ((a->ru_stime.tv_sec * 1000000 + a->ru_stime.tv_usec) -
                 (b->ru_stime.tv_sec * 1000000 + b->ru_stime.tv_usec)))
                / 1000000.0);
    }
}
bool check(const char *word, trie *root_ptr)
{
    char str[MAXCHAR];
    for(int j = 0; word[j]!=''; j++)
    {
        str[j]=word[j];
    }
    trie *trav_ptr = root_ptr;
    for(int i = 0; str[i]!=''; i++)
    {
        if (trav_ptr->paths[str[i] - 'a']==NULL)
        {
            return false;
        }
        else
        {
            trav_ptr=trav_ptr->paths[str[i] - 'a'];
        }
    }
    if (str==trav_ptr->word)
    {
        return true;
    }
    return false;
}
/**
 * Loads dictionary into memory. Returns true if successful else false.
 */
bool load(const char *dictionary, trie *root_ptr)
{
    FILE *file_ptr;
    char str[MAXCHAR];
    file_ptr = fopen(dictionary, "r");
    if (file_ptr == NULL){
        printf("Could not open file %s", dictionary);
        return false;
    }
    trie *trav_ptr = root_ptr;
    while (fgets(str, MAXCHAR, file_ptr) != NULL)
    {
        for(int i = 0; str[i]!=''; i++)
        {
            if (trav_ptr->paths[str[i] - 'a']==NULL)
            {
                trie *next_trie = malloc(sizeof(trie));
                trav_ptr->paths[str[i]-'a'] = next_trie;
                trav_ptr = next_trie;
            }
            else
            {
                trav_ptr=trav_ptr->paths[str[i] - 'a'];
            }
        }
        strcpy(trav_ptr->word, str);
    }
    return true;
}
/**
 * Returns number of words in dictionary if loaded else 0 if not yet loaded.
 */
void count(trie *root_ptr)
 {
    trie *trav_ptr = root_ptr;
    if (trav_ptr->word!=NULL)
    {
        size++;
    }
    for (int n = 0; n<26; n++)
    {
        if (trav_ptr->paths[n]!=NULL)
        {
            trav_ptr=trav_ptr->paths[n];
            count(trav_ptr);
        }
    }
}
unsigned int size(trie *root_ptr)
{
    count(root_ptr);
    return 0;
}
/**
 * Unloads dictionary from memory. Returns true if successful else false.
 */
bool unload(void)
{
    // TODO
    return false;
}

让我们考虑表达式trav_ptr->word->操作员说要做两件事:使用trav_ptr指向的结构,并参考其成员名为word。首先,为了使其起作用,trav_ptr必须指向有效的分配结构。然后,结果表达式成员word

接下来,wordchar数组。在大多数表达式中,当引用数组时,它会自动转换为数组的第一个元素的地址。

因此,这就是为什么编译器警告您将trav_ptr->word与NULL进行比较。永远不会无效;它必须始终是trav_ptr指向的结构中word的第一个元素的地址。

可能,您打算将trav_ptr与NULL进行比较。trav_ptr只是指针,而不是数组或结构成员。它可以指向结构,也可以是无效的。因此,当您获得trav_ptr的值时,您想检查它指向结构还是包含null。

关于size,您用unsigned int size(trie *root_ptr);声明了它。这使其成为一个函数,该函数需要trie *参数并返回unsigned int。这是您调用的函数,而不是可以增加的对象。

相关内容

  • 没有找到相关文章

最新更新