#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
, никак не инициализируется. Это определенно не строка с нулевым завершением.
У вас есть четыре возможных решения:
- Использовать
strcpy
вместоstrcat
для первого вызова:strcpy(loc,client_ip);
- Инициализируйте буфер, например, так:
loc[0] = ''; // Terminate the buffer, making it an "empty" string strcat(loc,client_ip);
- Вызовите
calloc
вместоmalloc
, так как это приведет к обнулению выделенной памяти, что аналогично установке всего этого на нулевой завершитель строки:char* loc = calloc(BUFSIZ, 1);
- Используется
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;
}
}