在 C 中使用 strcpy 和 strcat 的冲突?
conflict of using strcpy , strcat in C?
在下面的代码中,我试图逐个字符地加载单词的文本文件
然后我试图将每个完整的单词保存在哈希 table (字符串数组)中
但似乎 strcpy
保存了整个单词而不是单个 char
我不知道为什么。我在滥用 strcpy
和 strcat
吗?
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <stdbool.h>
bool load(const char* dictionary);
#define LENGTH 45
int main (int argc, char* argv[])
{
char* dictionary = argv[1];
load(dictionary);
return 0;
}
bool load(const char* dictionary)
{
int index = 0, words = 0, kk = 0;
int lastl = 0, midl = 0;
char word[LENGTH + 1];
char *wholeword[1001];
FILE* dic = fopen(dictionary, "r");
if (dic == NULL)
{
printf("Could not open %s.\n", dictionary);
return false;
}
for (int c = fgetc(dic); c != EOF; c = fgetc(dic))
{
// 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(dic)) != 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(dic)) != 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] = '[=10=]';
lastl = index - 1;
midl = (index - 1) % 3;
words++;
index = 0;
int hashi = (word[0] + word[lastl]) * (word[midl] + 17) % 1000;
wholeword[hashi] = (char*) malloc(sizeof(char) * (lastl + 2));
strcpy(wholeword[hashi], &word[0]); // ***
for (kk = 1; kk <= lastl + 1; kk++)
{
strcat(wholeword[words], &word[kk]);
}
}
}
fclose(dic);
return true;
}
Strcpy 不复制单个字符,它复制所有字符直到下一个空 ('[=12=]'
) 字节。要在您的代码中复制单个字符,请尝试:
wholeword[hashi] = &word[0];
而不是:
strcpy(wholeword[hashi], &word[0]);
是的,您误用了 strcpy
和 strcat
:这些函数将整个源字符串复制到目标数组(在 strcat
的现有字符串的末尾)。
以下几行:
wholeword[hashi] = (char*) malloc(sizeof(char) * (lastl + 2));
strcpy(wholeword[hashi], &word[0]); // ***
for (kk = 1; kk <= lastl + 1; kk++)
{
strcat(wholeword[words], &word[kk]);
}
}
可以用一次调用代替
wholeword[hashi] = strdup(word);
strdup()
分配内存,将参数字符串复制到其中,并 returns 指针。它在所有 Posix 系统上都可用,如果您没有它,请使用这两行:
wholeword[hashi] = malloc(lastl + 2);
strcpy(wholeword[hashi], word);
备注:
- 你假设你的散列是完美的,没有冲突。按照目前的编码,碰撞会导致前一个单词从字典中删除,并丢失其对应的记忆。
- 字典
char *wholeword[1001];
是load
函数中的局部变量。它是未初始化的,所以没有办法知道一个条目是否是指向一个词的有效指针。它应该被分配,初始化为 NULL
并返回给调用者。
在下面的代码中,我试图逐个字符地加载单词的文本文件
然后我试图将每个完整的单词保存在哈希 table (字符串数组)中
但似乎 strcpy
保存了整个单词而不是单个 char
我不知道为什么。我在滥用 strcpy
和 strcat
吗?
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <stdbool.h>
bool load(const char* dictionary);
#define LENGTH 45
int main (int argc, char* argv[])
{
char* dictionary = argv[1];
load(dictionary);
return 0;
}
bool load(const char* dictionary)
{
int index = 0, words = 0, kk = 0;
int lastl = 0, midl = 0;
char word[LENGTH + 1];
char *wholeword[1001];
FILE* dic = fopen(dictionary, "r");
if (dic == NULL)
{
printf("Could not open %s.\n", dictionary);
return false;
}
for (int c = fgetc(dic); c != EOF; c = fgetc(dic))
{
// 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(dic)) != 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(dic)) != 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] = '[=10=]';
lastl = index - 1;
midl = (index - 1) % 3;
words++;
index = 0;
int hashi = (word[0] + word[lastl]) * (word[midl] + 17) % 1000;
wholeword[hashi] = (char*) malloc(sizeof(char) * (lastl + 2));
strcpy(wholeword[hashi], &word[0]); // ***
for (kk = 1; kk <= lastl + 1; kk++)
{
strcat(wholeword[words], &word[kk]);
}
}
}
fclose(dic);
return true;
}
Strcpy 不复制单个字符,它复制所有字符直到下一个空 ('[=12=]'
) 字节。要在您的代码中复制单个字符,请尝试:
wholeword[hashi] = &word[0];
而不是:
strcpy(wholeword[hashi], &word[0]);
是的,您误用了 strcpy
和 strcat
:这些函数将整个源字符串复制到目标数组(在 strcat
的现有字符串的末尾)。
以下几行:
wholeword[hashi] = (char*) malloc(sizeof(char) * (lastl + 2));
strcpy(wholeword[hashi], &word[0]); // ***
for (kk = 1; kk <= lastl + 1; kk++)
{
strcat(wholeword[words], &word[kk]);
}
}
可以用一次调用代替
wholeword[hashi] = strdup(word);
strdup()
分配内存,将参数字符串复制到其中,并 returns 指针。它在所有 Posix 系统上都可用,如果您没有它,请使用这两行:
wholeword[hashi] = malloc(lastl + 2);
strcpy(wholeword[hashi], word);
备注:
- 你假设你的散列是完美的,没有冲突。按照目前的编码,碰撞会导致前一个单词从字典中删除,并丢失其对应的记忆。
- 字典
char *wholeword[1001];
是load
函数中的局部变量。它是未初始化的,所以没有办法知道一个条目是否是指向一个词的有效指针。它应该被分配,初始化为NULL
并返回给调用者。