0

我正在编写一个对文本进行编码以便可以将其放入 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%3Dis%26at

我希望输出为:

this%3Dthis%26that

关于如何实现我在 C 中尝试做的任何想法(没有库)?

4

5 回答 5

6

解决这个问题的一种方法是分配一个三倍大的第二个字符串,enteredCharStr然后一个接一个地复制字符,当你看到特殊字符时,写下替换。你希望它是原来的三倍,因为在最坏的情况下你需要替换几乎所有的字符。

于 2013-05-09T02:41:54.007 回答
1
#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;
}
于 2013-05-09T11:04:03.687 回答
0

我一个接一个地复制字符,如果我看到一个特殊字符,(在此代码中只有“#”)我复制 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;
}
于 2013-05-09T02:55:07.550 回答
0

您需要创建一个新字符串。这是一个例子:

char *str = "abc$ddd";
char *p = str;
char *buf = malloc(strlen(str)+1);
char *pbuf = buf;
while(*p) {
  if(*p != '$') *pbuf ++ = *p;
  p++;
}

它将从每个字节复制strbuf所有非$, 字节。

请注意,在您的情况下,您需要正确计算新字符串的大小。

于 2013-05-09T02:42:07.353 回答
0

AC 'string' 是一个固定大小的字符数组,因此没有内置的插入概念。您实际上是在询问如何将n字符插入数组的中间。

想到一个策略:

要在长度数组的x位置插入一个长度字符串: in

  • 调整数组的大小n+x(使用类似的东西realloc)。
  • 将每个字符洗牌,从一个位置i到另一个位置i+x
  • 将您的字符串写入x此 shuffle 操作现在释放的位置。

或者,分配一个大到足以容纳目标字符串的新数组(即,应用所有替换),然后通过从目标数组复制将结果写入其中,直到遇到要替换的字符,然后从替换字符串中复制,然后继续从原始源数组中读取。

于 2013-05-09T02:42:41.700 回答