如果字符串大于某个长度,我想将其截断为一定长度,并用句点(“。”)替换最后3个字符。我现在所拥有的是一个分段错误:
#define NAME_LENGTH 36
name is of type, char*.
if (strlen(name) > NAME_LENGTH){
//we need to truncate the name
printf("NAME IS TOO LONG.. TRUNCATING\n");
char *nCpy = NULL; //the truncated name
strncpy(nCpy, name, NAME_LENGTH); //copy NAME_LENGTH number of characters from name into nCpy
printf("Truncated name, now adding ...\n");
strcat(name, "..."); //append "..." to end of name
printf("... added, now copying to struct\n");
strcpy(record->name, nCpy); //assign our name in our record
printf("NAME IS NOW: %s\n", record->name);
}
运行时,如果名称长于NAME_LENGTH,则会出现分段错误。
Enter name > jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
NAME IS TOO LONG.. TRUNCATING
Segmentation fault (core dumped)
答案 0 :(得分:3)
你是segfaulting,因为你没有分配内存来存储nCpy指向的位置。
char *nCpy = NULL; //the truncated name
应该像
char *nCpy = malloc(sizeof(char) * NAME_LENGTH + 1); //the truncated name
你现在正在尝试写入内存中的一些垃圾值,谁知道,这几乎总是会导致分段错误。
正如Paul指出的那样,你需要为NAME_LENGTH字符分配空间,加上一个,因为字符串是以特殊的/0
字符终止的。
此特定错误称为dereferencing a null pointer
答案 1 :(得分:0)
你真的做了太多的字符串拷贝,并且之后没有释放副本,所以你最终会有很多泄露的内存。此外,还不清楚record->name
实际上是否足够长以容纳返回的字符串,但如果确实如此,您也可以在适当的位置构建名称。
这是一种可能性,它假定record->name
已经指向至少NAME_LENGTH + 1
个字节的存储空间:
if (strlen(name) > NAME_LENGTH)
snprintf(record->name, NAME_LENGTH + 1, "%.*s...", NAME_LENGTH - 3, name);
else
strncpy(record->name, name, NAME_LENGTH + 1);
这是另一种,可能更简单或可能更神秘的方式:
if (snprintf(record->name, NAME_LENGTH + 1, "%s", name) > NAME_LENGTH))
strcpy(record->name + NAME_LENGTH - 3, "...");