Результат Strcat, содержащий данные из последнего вызова strcat

#c #file #strcat

#c #файл #strcat

Вопрос:

Я сохраняю данные в двух разных файлах и использую 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 %sn",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 %sn",fileName);
            return false;
        }
        fprintf(fptr,"%s",content);
        fclose(fptr);
        return true;
    }
    
    return false;
}
 

Происходит то, что содержимое строки журнала помещается в начало 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.

Комментарии:

1. strcat(loc,client_ip); вызывает неопределенное поведение , поскольку loc заполняется неинициализированными данными и strcat ищет нулевой терминатор

2. Это было так глупо, спасибо за быстрый ответ! Видел людей, у которых возникли проблемы с неинициализированной строкой, но поскольку я не обнаружил ни одного случая моей проблемы, я подумал, что это не так.

Ответ №1:

strcat Функция требует, чтобы строка назначения действительно была правильной строкой с нулевым завершением. В противном случае это приведет к неопределенному поведению.

Буфер, который вы выделяете malloc , никак не инициализируется. Это определенно не строка с нулевым завершением.

У вас есть четыре возможных решения:

  1. Использовать strcpy вместо strcat для первого вызова:
     strcpy(loc,client_ip);
     
  2. Инициализируйте буфер, например, так:
     loc[0] = '';  // 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 .

Либо вызов free(loc) перед loc выходом из области видимости; Либо вместо этого создайте loc массив:

 char loc[BUFSIZ];
 

Создание loc массива вместо этого также означает, что вы можете легко его инициализировать:

 char loc[BUFSIZ] = { '' };
 

Ответ №2:

Loc неинициализирован, поведение strcat с uninit var не определено, в этом и была проблема. Замена первого вхождения strcat на strcpy решила проблему!

 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 %sn",loc);
          printf("Saving set to FALSE.");
          saving = false;
    }
}