为什么函数strcat不工作?

时间:2014-12-22 03:22:59

标签: c strcpy strcat

我在C中有一些代码,我想用字符串"选项"连接ssid。在for循环中

  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不起作用?

5 个答案:

答案 0 :(得分:3)

char *temp=strcat(strcat("<option>",ssid),"</option>");

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

答案 1 :(得分:1)

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

您可以阅读strcat() here

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

"<option>"只是在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中的字符数,<option></option>的字符数为17,您还需要额外的'\0' 1}}标记字符串结尾的字符,因此总strlen(ssid) + 18

答案 4 :(得分:0)

其他答案显示如何修复并仍然使用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;
}