- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一项任务要求我通过在一些给定代码中实现一些功能来编写一个拼写检查程序。由于某些语法错误,我无法编译。
首先是:
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/
我正在尝试学习 Fortran,并且看到了很多不同的定义,我想知道他们是否正在尝试完成同样的事情。以下有什么区别? 整数*4 整数(4) 整数(kind=4) 最佳答案 在 Fortran >=90
我以前从未编程过,最近(1 周前)才开始学习!第一门类(class)是函数式编程,使用 Haskell。 我有一项学校作业,我想通过删除一两个步骤来改进它,但我遇到了一个讨厌的错误。 基本上,我创建了
给定以下GraphQL请求和变量: 请求: query accounts($filter:AccountFilter, $first_:String, $skip_:Int) { accounts
我已经搜索了 StackOverflow,但找不到关于如何检查计算器应用程序的数字输入正则表达式的答案,该计算器应用程序将检查每个 keyup 的以下格式(jquery key up): 任何整数,例
类似于我上一篇致歉的文章,但没有那么长篇大论。基本上我想知道当每次重绘调用只重绘屏幕的一小部分时,优化重绘到 JFrame/JPanel 的最佳选择是什么。 此外,除了重绘重载之外,我并不是 100%
所以在我的教科书中有一个使用 f# 的递归函数的例子 let rec gcd = function | (0,n) -> n | (m,n) -> gcd(n % m,m);; 使用此功能,我的教科书
我有一个数据结构,例如表达式树或图形。我想添加一些“测量”功能,例如depth和 size . 如何最好地键入这些函数? 我认为以下三个变体的用处大致相同: depth :: Expr -> Int
这样写比较好 int primitive1 = 3, primitive2 = 4; Integer a = new Integer(primitive1); Integer b = new Inte
我是 Java 8 新手,想根据键对 Map 进行排序,然后在值内对每个列表进行排序。 我试图寻找一种 Java 8 方法来对键和值进行排序。HashMap>映射 map.entrySet().str
这就是我的目标... vector ,int> > var_name (x, pair (y),int>); 其中 x 是 vector var_name 的大小,y 是对内 vector 的大小。
这里是 an answer to "How do I instantiate a Queue object in java?" , Queue is an interface. You can't i
这个问题在这里已经有了答案: Weird Integer boxing in Java (12 个答案) Why are autoboxed Integers and .getClass() val
我们可以使用 C++ STL 做这样的事情吗?如果是,我将如何初始化元素?我试图这样做,但没有成功。 pair,vector>p; p.first[0]=2; 最佳答案 Can we do som
您好,我正在尝试为百分比和整数数组中的数字找到索引。假设 arraynum = ['10%','250','20%','500'] 并且用户发送一个值 15%,这个数字在哪个范围内居住?我可以使用这段
我与三列有关系:ProductName、CategoryID 和 Price。我需要选择仅那些价格高于给定类别中平均产品价格的产品。(例如,当apple(ProductName)是fruit(Cate
我已经坚持了一段时间,我正在尝试将一些数据配对在一起。这是我的代码。 #include #include using namespace std; int main() { pair data(
我收到错误:'(Int, Int)' 与 'CGPoint' 不相同 如何将 (Int, Int) 转换为 CGPoint let zigzag = [(100,100), (100,150)
我在 .cpp 文件中发现了以下代码。我不理解涉及头文件的构造或语法。我确实认识到这些特定的头文件与 Android NDK 相关。但是,我认为这个问题是关于 C++ 语法的一般问题。这些在某种程度上
我将这些输入到 Scala 解释器中: val a : Integer = 1; val b : Integer = a + 1; 我收到消息: :5: error: type mismatch;
C++:vector>v(size);当我试图打印出值时显示 0 作为值,但是当未声明 vector 大小时它显示正确的输出?为什么这样?例如: int x; cin>>x; vector>v(x);
我是一名优秀的程序员,十分优秀!