在 C 中使用 strcpy 和 strcat 的冲突?

conflict of using strcpy , strcat in C?

在下面的代码中,我试图逐个字符地加载单词的文本文件 然后我试图将每个完整的单词保存在哈希 table (字符串数组)中 但似乎 strcpy 保存了整个单词而不是单个 char 我不知道为什么。我在滥用 strcpystrcat 吗?

# 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]);

是的,您误用了 strcpystrcat:这些函数将整个源字符串复制到目标数组(在 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 并返回给调用者。