【发布时间】:2021-11-13 23:07:19
【问题描述】:
我正在编写一个代码,该代码从标准输入读取输入文件,并输出完全相同的内容(到标准输出),除了按以下方式替换“字典”中找到的任何单词,按确切顺序:
- 如果出现与字典中作为键存储的单词完全相同的单词,则找到相应的值对并将其打印出来。
- 如果正确大写的单词(例如,Thomas,首字母大写,其他所有字母小写)是字典中的有效键,则打印出相应的值对
- 如果小写版本是有效键,则打印出其对应的值
- 如果没有匹配项,则按原样打印出来。 (所有非字母字符都只是“正常”打印出来。)
我一直遇到的一个问题是,当我在做 (2) 时,当我测试“ IPSUM”(全部大写)。
例如,看这个输出: 我的输出在带有“”表示应该是什么。根据我检查的顺序,由于 IPSUM 不在字典中(请参阅本文末尾的字典内容),它转到(2) IPSUM 应该成为 Ipsum 的地方,它应该打印出相应的值伊普苏姆。但相反,我得到了 IpsumU,所以字典无法识别这个词。但我不确定“U”是从哪里来的,因为输入是准确的
IPSUM(全部大写)。
谁能帮我弄清楚我的代码可能有什么问题?
//for reference:
typedef struct HashBucketEntry {
void *key;
void *data;
struct HashBucketEntry *next;
} HashBucketEntry;
typedef struct HashTable {
int size;
unsigned int (*hashFunction)(void *);
int (*equalFunction)(void*, void*);
HashBucketEntry **buckets;
} HashTable;
//We have a Hashtable *dictionary.
void processInput() {
//char c;
int c;
int i = 0;
//char * word = (char *) malloc(60 * sizeof(char));
char word[60];
while (c = getchar()) {
if (isalpha(c)) {
word[i] = c;
i++;
} else {
word[i] = '\0';
if (word[0] != '\0') {
//char * copy = (char *) malloc(60 * sizeof(char));
char copy[60];
strcpy(copy, word);
unsigned int location = (dictionary->hashFunction)(copy) % (dictionary->size);
char * word_in_dict;
if (dictionary->buckets[location] != NULL) {
word_in_dict = (char *) dictionary->buckets[location]->data;
} else {
word_in_dict = NULL;
}
char copy2[60];
copy2[0] = toupper(copy[0]);
for(int i = 1; copy[i]; i++){
copy2[i] = tolower(copy[i]);
}
unsigned int location2 = (dictionary->hashFunction)(copy2) % (dictionary->size);
char * word_in_dict2;
if (dictionary->buckets[location2] != NULL) { //somehow this is NULL when IPSUM, even though copy2 has correct string
word_in_dict2 = (char *) dictionary->buckets[location2]->data;
} else {
word_in_dict2 = NULL;
}
char copy3[60];
for(int i = 0; copy[i]; i++){
copy3[i] = tolower(copy[i]);
}
unsigned int location3 = (dictionary->hashFunction)(copy3) % (dictionary->size);
char * word_in_dict3;
if (dictionary->buckets[location3] != NULL) {
word_in_dict3 = (char *) dictionary->buckets[location3]->data;
} else {
word_in_dict3 = NULL;
}
if (word_in_dict != NULL) {
fprintf(stdout, "%s", word_in_dict);
} else if (word_in_dict2 != NULL) {
fprintf(stdout, "%s", word_in_dict2);
} else if (word_in_dict3 != NULL) {
fprintf(stdout, "%s", word_in_dict3);
} else {
//fprintf(stdout, "%s", copy);
printf("%s", copy);
}
putchar(c);
i = 0;
} else if (c != EOF) {
putchar(c);
} else {
break;
}
}
}
}
字典只包含以下条目:
ipsum i%#@!
fubar fubar
IpSum XXXXX24
Ipsum YYYYY211
任何帮助将不胜感激!
响应答案更新: 我将 copy2 的代码更改为:
for(j = 1; j < strlen(copy); j++) {
if (j < sizeof(copy2)) {
copy2[j] = tolower(copy[j]);
}
}
(并做了与 copy3 类似的事情)。第二种情况有效,但现在第三种情况失败;只有当我改变第二种情况而不是第三种情况时,事情似乎才有效。有谁知道为什么会这样?
【问题讨论】:
-
首先,
char c必须是int c,因为fgetc()返回int。认为“字符必须是char”(或“数字必须是整数”)是初学者的错误。其次,循环结束条件不正确。应该是while ((c = getchar()) != EOF) -
...我看到你已经处理了循环体末尾的
EOF,使代码变得笨拙且难以理解。 -
请以文字形式发布Minimal Reproducible Example,最短的完整代码,显示您尝试过的内容。
-
请edit您的问题,并以文本形式显示(复制和粘贴)预期和实际,并明确哪个是什么。
IPSUM (all cap).是唯一的输入吗? -
@WeatherVane 我已经修复了代码,希望它更好一点!
标签: arrays c string pointers char