Strcat 结果包含上次 strcat 调用的数据

Strcat result having data from last strcat call

我将数据保存在两个不同的文件中并使用 strcat 连接这些数据。 奇怪的是,我最后一次 strcat 调用的结果得到了我现在想要连接的两个字符串的连接。 可能有点模糊所以这是代码:

...
strcat(logline,"\n");
if(logging){
    if(writeInFile(logfile,"a",logline))
         printf("    Connection logged.");
    else
         printf("    Connection couldn't be logged.");        
}

if(saving){
    char* loc = (char*) malloc(BUFSIZ);
    strcat(loc,client_ip);
    strcat(loc,"-");
    strcat(loc,server_ip);
    strcat(loc,".txt");

    if(writeInFile(loc,"a",request)){
          printf("    Connection saved.");
    }
    else{
          printf("ERROR: cannot create/open savefile %s\n",loc);
          printf("Saving set to FALSE.");
          saving = false;
    }
}
bool writeInFile(char* fileName, char* openingParam, char* content){
    if(strcmp(openingParam,"a") == 0 || strcmp(openingParam,"w") == 0){
        FILE* fptr = NULL;
        fptr = fopen(fileName,openingParam);
        if ( fptr == NULL)
        {
            printf("ERROR: cannot create/open logfile %s\n",fileName);
            return false;
        }
        fprintf(fptr,"%s",content);
        fclose(fptr);
        return true;
    }
    
    return false;
}

发生的事情是将logline 的内容放在loc 的开头。 所以创建了一个名字很长的文件。

编辑 :: 该文件应该命名为 192.168.1.36-192.168.1.36.txt

但取名为

|--> timestamp = Sat Jan  2 20:09:24 2021
|--> remote    = 192.168.1.36
|--> local     = 192.168.1.36
|--> request   = [timeout]
|--> END
192.168.1.36-192.168.1.36.txt
|--> timestamp = Sat Jan  2 20:09:24 2021
|--> remote    = 192.168.1.36
|--> local     = 192.168.1.36
|--> request   = [timeout]
|--> END

是通过strcat得到的logline的值。

strcat 函数要求目标字符串确实是一个正确的以 null 结尾的字符串。否则会导致未定义的行为.

您使用 malloc 分配的缓冲区未以任何方式初始化。它绝对不是以 null 结尾的字符串。

您有四种可能的解决方案:

  1. 第一次调用使用strcpy代替strcat

    strcpy(loc,client_ip);
    
  2. 初始化缓冲区,例如像这样:

    loc[0] = '[=11=]';  // Terminate the buffer, making it an "empty" string
    strcat(loc,client_ip);
    
  3. 调用 calloc 而不是 malloc,因为这会将分配的内存归零,这与将其全部设置为字符串空终止符相同:

    char* loc = calloc(BUFSIZ, 1);
    
  4. 使用snprintf将字符串“打印”到未初始化的缓冲区中:

    snprintf(loc, BUFSIZ, "%s-%s.txt", client_ip, server_ip);
    

个人推荐方法4,使用snprintf.


您的代码还有另一个问题:内存泄漏,因为您没有传递分配给 free 的内存。

要么在 loc 超出范围之前调用 free(loc);要么或者将 loc 改为数组:

char loc[BUFSIZ];

制作 loc 数组也意味着您可以轻松地初始化它:

char loc[BUFSIZ] = { '[=15=]' };

Loc 未初始化,uninit var 的 strcat 行为未定义,这就是问题所在。 用 strcpy 替换第一次出现的 strcat 解决了它!

if(saving){
    char* loc = (char*) malloc(BUFSIZ);
    strcpy(loc,client_ip);
    strcat(loc,"-");
    strcat(loc,server_ip);
    strcat(loc,".txt");

    if(writeInFile(loc,"a",request)){
          printf("    Connection saved.");
    }
    else{
          printf("ERROR: cannot create/open savefile %s\n",loc);
          printf("Saving set to FALSE.");
          saving = false;
    }
}