"apelle figlio di apollo"
。我想在"a$11$ figlio di apollo"
中放入riga_corrente
,但我只得到"a$11$ fig"
,我不明白为什么。
部分代码:
strcpy(temp,strtok(riga_corrente,d[i].stringa));
strcat(temp,compresso_s);
strcat(temp,strtok(NULL,d[i].stringa));
strcpy(riga_corrente,temp);
答案 0 :(得分:0)
您的问题在这里转换为MCVE(Minimal, Complete, Verifiable Example):
#include <stdio.h>
#include <string.h>
int main(void)
{
char riga_corrente[200] = "apelle figlio di apollo";
char stringa[] = "pelle";
char compresso_s[] = "$11$";
char temp[200];
strcpy(temp, strtok(riga_corrente, stringa));
strcat(temp, compresso_s);
strcat(temp, strtok(NULL, stringa));
strcpy(riga_corrente, temp);
printf("[%s]\n", riga_corrente);
return 0;
}
这将产生以下输出,这意味着库函数正在按设计工作(但显然不是您期望的那样):
[a$11$ fig]
对strtok()
的第一次调用在p
中的apelle
处停止,用空字节换行,然后返回指向a
的指针,该指针被复制到temp
。然后,您从$11$
附加compresso_s
。对strtok()
的下一次调用会跳过e
的{{1}},l
,l
和e
,并在空白处开始令牌。字母apelle
,f
,i
与定界符不匹配,但是g
匹配,因此l
中的l
用空字节并返回指向空白的指针。将该字符串正确添加到figlio
的末尾,然后temp
由于temp
覆盖riga_corrente
。
乍一看,您可以通过将第二个调用中的定界符更改为strcpy()
来解决它,也许只是换行符,甚至是空字符串。但是,这也将strtok()
的{{1}}作为输出的一部分。需要不同技术的修复-可能使用自1989年以来在标准C中已被低估(鲜为人知)的strspn()
和strcspn()
函数,或者可能使用strstr()
查找字符串elle
。
它不是很优雅(这里可能有一个函数试图转义),但这可以起作用:
apelle
这里没有缓冲区溢出保护;通常不需要它,但是原则上,如果pelle
从未出现在#include <stdio.h>
#include <string.h>
int main(void)
{
char riga_corrente[200] = "apelle figlio di apollo";
char stringa[] = "pelle";
char compresso_s[] = "$11$";
char temp[200];
char *source = riga_corrente;
char *p1 = strstr(source, stringa);
if (p1 == NULL)
strcpy(temp, source);
else
{
*p1 = '\0';
strcpy(temp, source);
source = p1 + strlen(stringa);
}
strcat(temp, compresso_s);
if (p1 != NULL)
{
p1 = strstr(source, stringa);
if (p1 == NULL)
strcat(temp, source);
else
{
*p1 = '\0';
strcat(temp, source);
}
}
strcpy(riga_corrente, temp);
printf("[%s]\n", riga_corrente);
return 0;
}
中,则可能会导致缓冲区溢出。