【问题标题】:why the function strcat not working?为什么函数 strcat 不起作用?
【发布时间】:2015-02-20 04:02:11
【问题描述】:

我有一些 C 代码,我想在 for 循环中将 ssid 与字符串“option”连接起来

  void ApListCallback(ScanResult *pApList)
    {
        int i;

      printf("Find %d APs: \r\n", pApList->ApNum);

        for (i=0;i<pApList->ApNum;i++){
            char *ssid=pApList->ApList[i].ssid;
            char *temp=strcat(strcat("<option>",ssid),"</option>");
            printf("=======%s=======\r\n",ssid);
            printf("-------%s-------\r\n",temp);
            strcpy(ApListCallbackSelectStr, temp);
        }

        printf("---%s--\r\n",ApListCallbackSelectStr);
        }

我得到了结果:

找到 11 个 AP:

=======MODIM FASHION=======
-------<option>-------
==============
-------<option>-------
=======360WiFi-6888=======
-------<option>-------
=======HAME_A5_037d=======
-------<option>-------
=======sweet baby=======
-------<option>-------
=======ringierguest=======
-------<option>-------
=======JIMMY 3G=======
-------<option>-------
=======MF70_9BC5E1=======
-------<option>-------
=======Bert-Co=======
-------<option>-------
---<option>--

为什么函数 strcat 不起作用?

【问题讨论】:

  • 你的预期输出是什么
  • 你也不应该 printf \r\n (除非你在 Unix 环境下运行时故意生成一个 windows 文本文件)。在 Windows 中,打印 \n 将导致文件包含 \r\n。
  • 循环的每次迭代都会调用strcpy(ApListCallbackSelectStr,它会覆盖该缓冲区中的内容;所以这段代码的效果(如果固定的话)是打印出每个项目,然后打印最后一行两次;这真的是你想要的吗?
  • @MattMcNabb 是的。你说的对。我需要使用strcat 而不是strcpy 函数

标签: c strcpy strcat


【解决方案1】:

其他答案显示了如何修复并仍然使用 strcat。然而,用 C 编写此代码的更好方法是:

printf("=======%s=======\n",ssid);
printf("-------<option>%s</option>-------\n", ssid);

你不需要分配内存或任何东西。

如果您还将每一行编译成一个字符串,那么您还必须注意要写入的缓冲区大小。您必须防止ApListCallbackSelectStr 上的缓冲区溢出。这是一种方法:

char *begin = ApListCallbackSelectStr;
char *const end = begin + sizeof ApListCallbackSelectStr;
// assuming `ApListCallbackSelectStr` is an array, not a pointer

for (i=0;i<pApList->ApNum;i++)
{    
    char const *ssid = pApList->ApList[i].ssid;
    int this = snprintf(begin, end - begin, 
                    "-------<option>%s</option>-------\n", ssid);

    if ( this < 0 || this >= end - begin )    // ran out of buffer, or other internal failure
        return; 

    printf("======%s======\n", ssid);
    printf("%*s\n", this, begin);

    begin += this;
}

【讨论】:

    【解决方案2】:

    如果您查找 strcat 的联机帮助页,您会看到第一个参数应该是一个 char[] 缓冲区来保存结果。与较新的语言不同,C 中的字符串是字符数组,因此必须这样操作。此外, strcat 只复制一个参数,而不是一个可变参数列表。试试

    char line[1000] = "";
    strcat(line, "<option>");
    strcat(line, ssid);
    strcat(line, "</option>");
    printf("%s\n", line);
    

    【讨论】:

      【解决方案3】:

      "&lt;option&gt;" 在 C 语言中是只读的,因此尝试向其写入数据,实际上应该会导致分段错误,您需要一个指向已分配内存的指针才能写入它,以下应该可以工作

      void ApListCallback(ScanResult *pApList)
      {
          int i;
      
          printf("Find %d APs: \r\n", pApList->ApNum);
      
          for (i=0;i<pApList->ApNum;i++)
          {
              char *ssid=pApList->ApList[i].ssid;
              /* reserve memory for the characters and point to it with temp */
              char *temp=malloc(strlen(ssid) + 18);
              if (temp != NULL)
              {
                  /* copy the first part of the resulting string into temp */
                  strcpy(temp, "<option>");
                  /* append ssid to temp */
                  strcat(temp, ssid);
                  /* append the literal "</option>" to temp */
                  strcat(temp, "</option>");
                  strcpy(ApListCallbackSelectStr, temp);
                  /* release the reserved memory */
                  free(temp);
              }
          }
      
          printf("---%s--\r\n",ApListCallbackSelectStr);
      }
      

      strlen函数会返回字符串ssid的字符数,&lt;option&gt;&lt;/option&gt;的字符数是17,你还需要一个额外的'\0'字符来标记结束字符串,所以总计strlen(ssid) + 18。

      【讨论】:

      • 感谢您的回答。看来我用C语言的Java思维XD
      【解决方案4】:

      您不能使用字符串文字作为strcat() 的第一个参数。第一个参数需要包含足够的空间来包含原始字符串加上连接的字符串(加上终止零)。

      你可以阅读strcat()here。

      【讨论】:

        【解决方案5】:
        char *temp=strcat(strcat("<option>",ssid),"</option>");
        

        在这里,您尝试连接到字符串文字 "&lt;option&gt;"。问题是:修改字符串文字是未定义的行为。

        【讨论】:

          猜你喜欢
          • 2015-10-09
          • 2014-08-06
          • 2021-08-20
          • 2021-07-25
          • 2013-08-26
          • 2011-11-13
          • 2023-03-15
          • 2021-08-26
          • 1970-01-01
          相关资源
          最近更新 更多