C-用字符串替换字符
我正在编写一个程序,对文本进行编码,这样就可以将其放入URL。我让用户输入一个字符串,如果它包含特殊字符(#、%、&、?等),则用相应的字符代码(%23、%25、%26、%3F等)替换它们。问题是特殊字符的长度仅为1,而代码的长度为3。代码最终会替换特殊字符之后的字符。这是我用来替换的代码C-用字符串替换字符,c,C,我正在编写一个程序,对文本进行编码,这样就可以将其放入URL。我让用户输入一个字符串,如果它包含特殊字符(#、%、&、?等),则用相应的字符代码(%23、%25、%26、%3F等)替换它们。问题是特殊字符的长度仅为1,而代码的长度为3。代码最终会替换特殊字符之后的字符。这是我用来替换的代码 char *p = enteredCharStr; while ((p = strstr(p, specialCharArr[x])) != NULL ) { char *substr; su
char *p = enteredCharStr;
while ((p = strstr(p, specialCharArr[x])) != NULL )
{
char *substr;
substr = strstr(enteredCharStr, specialChar[x]);
strncpy(substr, charCodesArr[x], 3);
p++;
}
将我的程序与输入一起使用的输出示例:“this=this&that”
我希望输出为:
this%3Dthis%26that
有没有关于如何实现我在C(无库)中尝试执行的操作的想法?解决此问题的一种方法是分配第二个字符串,该字符串的大小是enteredCharStr的三倍,并逐个复制字符,当您看到特殊字符时,则编写重放。您希望它是三倍大,因为在最坏的情况下,您需要替换几乎所有的字符。您需要创建一个新字符串。下面是一个例子:
char *str = "abc$ddd";
char *p = str;
char *buf = malloc(strlen(str)+1);
char *pbuf = buf;
while(*p) {
if(*p != '$') *pbuf ++ = *p;
p++;
}
它将从str
复制到buf
所有非$
,每个字节一个字节
请注意,在您的情况下,您需要对新字符串的大小进行正确的计算。C“string”是一个固定大小的字符数组,因此没有内置的插入概念。您实际上是在询问如何在数组中间插入
n
字符
我想到一个策略:
要在长度为n
的数组的i
位置插入长度为x
的字符串,请执行以下操作:
- 将数组调整为大小
(使用类似于n+x
的方法)李>realloc
- 将位置
以外的每个字符洗牌到位置i
i+x
- 将字符串写入此洗牌操作现在释放的
位置李>x
或者,分配一个足以容纳目标字符串的新数组(即,应用所有替换),然后通过从目标数组复制直到遇到要替换的字符,然后从替换字符串复制,将结果写入该数组,然后继续从原始源数组中读取。我正在一个接一个地复制字符,如果我看到一个特殊字符,(在本代码中仅“#”) 我复制3个字符,将索引增加到输出缓冲区中3。 您还可以做一些更聪明的事情来猜测缓冲区的大小,并可能在整个操作中循环,每次缓冲区溢出时都将其大小加倍
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
if (argc != 2) {
exit(1);
}
char* input = argv[1];
int bufferSize = 128;
char* output = malloc(bufferSize);
int outIndex = 0;
int inIndex = 0;
while(input[inIndex] != '\0'){
switch (input[inIndex])
{
case '#':·
if(outIndex + 4 > bufferSize){
// Overflow, retry or something.
exit(2);
}
output[outIndex] = '%';
output[outIndex+1] = '2';
output[outIndex+2] = '3';
outIndex = outIndex + 3;
inIndex = inIndex + 1;
break;
// Other cases
default:
if(outIndex + 2 > bufferSize){
exit(2);
}
output[outIndex] = input[inIndex];
outIndex = outIndex + 1;
inIndex = inIndex + 1;
break;
}
}
output[outIndex] = '\0';
printf("%s\n", output);
return 0;
}
#包括
#包括
int main(int argc,char*argv[]){
如果(argc!=2){
出口(1);
}
char*input=argv[1];
int bufferSize=128;
char*output=malloc(缓冲区大小);
int-outinex=0;
int-inIndex=0;
while(输入[inIndex]!='\0'){
开关(输入[inIndex])
{
案例“#”:·
如果(outIndex+4>bufferSize){
//溢出、重试或其他。
出口(2);
}
输出[OUTIDEX]='%';
输出[outIndex+1]=“2”;
输出[OUTIDEX+2]=“3”;
outIndex=outIndex+3;
inIndex=inIndex+1;
打破
//其他情况
违约:
如果(outIndex+2>bufferSize){
出口(2);
}
输出[outIndex]=输入[inIndex];
outIndex=outIndex+1;
inIndex=inIndex+1;
打破
}
}
输出[OUTIDEX]='\0';
printf(“%s\n”,输出);
返回0;
}
#包括
#包括
#包括
int是特殊的(INTC){
静态字符表[]=“#%&”=“;//添加等。。
返回strchr(表c)?1:0;
}
字符*编码(常量字符*s){
大小\u t capa=1024;
char*buff=malloc(capa*sizeof(char));
大小\u t大小=0;
对于(;*s;++s){
如果(尺寸+3>capa){
capa+=32;
buff=realloc(buff,capa*sizeof(char));
}
如果(是特殊的(*s)){
大小+=sprintf(buff+size,%%%02x,*s);
}否则{
大小+=sprintf(buff+大小,“%c”,*s);
}
}
如果(尺寸=capa){
buff=realloc(buff,(大小+1)*sizeof(字符));
}
buff[size++]='\0';
返回realloc(buff,size*sizeof(char));
}
内部主(空){
char*enteredCharStr=“this=this&that”;
char*p=encode(输入charstr);
printf(“%s\n”,p);
自由基(p);
返回0;
}
1)确保最后一个字符串有足够的存储空间,否则会导致缓冲区溢出并导致程序崩溃。2) 在要替换的内容之后复制所有内容,前面有足够的字符,因此不会被覆盖。3) 在现场写下重置值。快速,简单,O(n)。如今,内存优化已经不那么重要了,在迭代结束时,第二个字符串将包含所有字符加上替换的字符,或者第二个字符串将只包含替换的字符?@mjrichards在迭代结束时,第二个字符串将包含所有字符,并用字符代码替换特殊字符。太棒了!让我思考的道具。绝对是我需要做的。你能详细解释一下一切是如何工作的吗?@mjrichards将该区域作为一个字符串动态地保护起来,并在那里写入。对于程序如何知道用哪个代码替换字符,我有点困惑。我知道它发生在size+=sprintf(buff+size,%%%02x,*s)代码>但不确定how@mjrichards如果要输出%%
本身,请执行%%
为什么%%
是printf中的控制字符%02x
是通过在两个宽度数字中添加前导零以十六进制值的形式输出的。
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
if (argc != 2) {
exit(1);
}
char* input = argv[1];
int bufferSize = 128;
char* output = malloc(bufferSize);
int outIndex = 0;
int inIndex = 0;
while(input[inIndex] != '\0'){
switch (input[inIndex])
{
case '#':·
if(outIndex + 4 > bufferSize){
// Overflow, retry or something.
exit(2);
}
output[outIndex] = '%';
output[outIndex+1] = '2';
output[outIndex+2] = '3';
outIndex = outIndex + 3;
inIndex = inIndex + 1;
break;
// Other cases
default:
if(outIndex + 2 > bufferSize){
exit(2);
}
output[outIndex] = input[inIndex];
outIndex = outIndex + 1;
inIndex = inIndex + 1;
break;
}
}
output[outIndex] = '\0';
printf("%s\n", output);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int isspecial(int c){
static char table[] = "#%&?=<>"; //add etc..
return strchr(table, c) ? 1 : 0;
}
char *encode(const char *s){
size_t capa = 1024;
char *buff=malloc(capa*sizeof(char));
size_t size = 0;
for(;*s;++s){
if(size + 3 > capa){
capa += 32;
buff = realloc(buff, capa*sizeof(char));
}
if(isspecial(*s)){
size+=sprintf(buff+size, "%%%02x", *s);
} else {
size+=sprintf(buff+size, "%c", *s);
}
}
if(size == capa){
buff=realloc(buff, (size+1)*sizeof(char));
}
buff[size++]='\0';
return realloc(buff, size*sizeof(char));
}
int main(void){
char *enteredCharStr = "this=this&that";
char *p = encode(enteredCharStr);
printf("%s\n", p);
free(p);
return 0;
}