【问题标题】:conflict of using strcpy , strcat in C?在 C 中使用 strcpy 和 strcat 的冲突?
【发布时间】:2017-03-15 01:52:59
【问题描述】:

在下面的代码中,我试图逐个字符地加载单词的文本文件 然后我试图将每个完整的单词保存在哈希表(字符串数组)中 但似乎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] = '\0';
      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 函数,顾名思义,复制一个字符串。 wword 是什么?
  • 你试过用调试器单步调试代码吗?
  • @DavidSchwartz wword 在这里错字(我编辑它)是全字(字符串数组),谢谢

标签: c strcpy strcat


【解决方案1】:

是的,您误用了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() 分配内存,将参数字符串复制到其中并返回指针。它在所有 Posix 系统上都可用,如果您没有,请使用以下 2 行:

  wholeword[hashi] = malloc(lastl + 2);
  strcpy(wholeword[hashi], word);

注意事项:

  • 您假设您的哈希是完美的,没有冲突。按照目前的编码,冲突会导致前一个单词从字典中删除,并丢失相应的内存。
  • 字典char *wholeword[1001];load 函数中的一个局部变量。它是未初始化的,因此无法知道一个条目是否是一个指向单词的有效指针。它应该被分配、初始化为NULL 并返回给调用者。

【讨论】:

    【解决方案2】:

    Strcpy 不会复制单个字符,它会复制所有字符,直到下一个空 ('\0') 字节。要在代码中复制单个字符,请尝试:

    wholeword[hashi] = &word[0];
    

    代替:

    strcpy(wholeword[hashi], &word[0]);
    

    【讨论】:

    • 请不要在数组下标之前放置空格——它们绑定得非常紧密,不应该这样间隔。例如,在&amp;word [0] 中,优先级是&amp;(word [0]) 而不是(&amp;word) [0]
    猜你喜欢
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 2016-12-03
    • 1970-01-01
    • 2013-08-23
    • 2015-08-16
    • 2021-08-24
    • 2010-11-19
    相关资源
    最近更新 更多