Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-用字符串替换字符_C - Fatal编程技术网

C-用字符串替换字符

C-用字符串替换字符,c,C,我正在编写一个程序,对文本进行编码,这样就可以将其放入URL。我让用户输入一个字符串,如果它包含特殊字符(#、%、&、?等),则用相应的字符代码(%23、%25、%26、%3F等)替换它们。问题是特殊字符的长度仅为1,而代码的长度为3。代码最终会替换特殊字符之后的字符。这是我用来替换的代码 char *p = enteredCharStr; while ((p = strstr(p, specialCharArr[x])) != NULL ) { char *substr; su

我正在编写一个程序,对文本进行编码,这样就可以将其放入URL。我让用户输入一个字符串,如果它包含特殊字符(#、%、&、?等),则用相应的字符代码(%23、%25、%26、%3F等)替换它们。问题是特殊字符的长度仅为1,而代码的长度为3。代码最终会替换特殊字符之后的字符。这是我用来替换的代码

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;
}