gpt4 book ai didi

c - 问题理解数据分配和无符号整数的一个方面

转载 作者:太空宇宙 更新时间:2023-11-04 03:19:55 25 4
gpt4 key购买 nike

我有一项任务要求我通过在一些给定代码中实现一些功能来编写一个拼写检查程序。由于某些语法错误,我无法编译。

首先是:

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 的工作原理。为 struct trie 分配内存时

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

我的结构体的char字段不是NULL吗?因为我还没有填充任何东西。

至于另一个错误,我认为我不能增加 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] text\n");
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 WORDS\n\n");

// 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] = '\0';

// 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("%s\n", 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: %d\n", misspellings);
printf("WORDS IN DICTIONARY: %d\n", n);
printf("WORDS IN TEXT: %d\n", words);
printf("TIME IN load: %.2f\n", time_load);
printf("TIME IN check: %.2f\n", time_check);
printf("TIME IN size: %.2f\n", time_size);
printf("TIME IN unload: %.2f\n", time_unload);
printf("TIME IN TOTAL: %.2f\n\n",
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]!='\0'; j++)
{
str[j]=word[j];
}
trie *trav_ptr = root_ptr;
for(int i = 0; str[i]!='\0'; 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]!='\0'; 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

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

所以这就是编译器警告您将 trav_ptr->word 与 NULL 进行比较的原因。它永远不能为空;它必须始终是trav_ptr 指向的结构中word 的第一个元素的地址。

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

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

关于c - 问题理解数据分配和无符号整数的一个方面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47424957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com