将字符串截断到一定长度,然后在C中将字符添加到末尾

时间:2013-11-16 21:43:10

标签: c string

如果字符串大于某个长度,我想将其截断为一定长度,并用句点(“。”)替换最后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)

2 个答案:

答案 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, "...");