C 用数组中存储的字符替换字符串中的某些字符会插入垃圾

C 用数组中存储的字符替换字符串中的某些字符会插入垃圾,c,arrays,string,char,C,Arrays,String,Char,我一直在尝试将字符串中的字符替换为存储在某些数组中的字符: char encode_table[122]; char decode_table[122]; ... int main() { memset(encode_table, 0, 122); memset(decode_table, 0, 122); ... 为了填充表格,我使用以下格式的文件 a b c d 其中a映射到b,c映射到d,等等。我将映射存储在数组中,使用映射字符的ASCII值作为索引 enc

我一直在尝试将字符串中的字符替换为存储在某些数组中的字符:

char encode_table[122];
char decode_table[122];

...

int main()
{
    memset(encode_table, 0, 122);
    memset(decode_table, 0, 122);
    ...
为了填充表格,我使用以下格式的文件

a b
c d
其中a映射到b,c映射到d,等等。我将映射存储在数组中,使用映射字符的ASCII值作为索引

encode_table[97] // Asking for the mapping of 'a'. Returns 'b'
映射完所有字符后,我逐行解析一个文件。每一行都由另一个函数处理,该函数应该替换必须替换的字符,而不处理其余的字符

void display(char * filename){
    char buffer[255];
    FILE * file = fopen(filename, "r");
    ...
    while(fgets(buffer, sizeof(buffer), file){
        display_line(buffer);
    }
}

void display_line(char * line){
    char c;
    char c_r;
    char format_str[255];

    if(encode || decode){
        for(int i = 0; i < strlen(line); i++){
            c = line[i];
            c_r = (encode ? encode_table[(int)c] : decode_table[(int)c]);

            if((int)c != O){  // don't print empty chars in the buffer
                if(c == EOF){
                    break;
                }
                if((int)c_r != 0){
                    format_str[strlen(format_str)] = c_r;
                }
                else{
                    format_str[strlen(format_str)] = c;
                }
            }
        }
        printf("%s", format_str);
        memset(format_str, 0, strlen(format_str)); // reset char array for next iteration
}
解码表:

{0: , 1: , 2: , 3: , 4: , 5: , 6: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 14: , 15: , 16: , 17: , 18: , 19: , 20: , 21: , 22: , 23: , 24: , 25: , 26: , 27: , 28: , 29: , 30: , 31: , 32: , 33: , 34: , 35: , 36: , 37: , 38: , 39: , 40: , 41: , 42: , 43: , 44: , 45: , 46: , 47: , 48: , 49: , 50: , 51: , 52: , 53: , 54: , 55: , 56: , 57: , 58: , 59: , 60: , 61: , 62: , 63: , 64: , 65: Z, 66: Y, 67: X, 68: W, 69: V, 70: U, 71: T, 72: S, 73: R, 74: Q, 75: P, 76: O, 77: N, 78: M, 79: L, 80: K, 81: J, 82: I, 83: H, 84: G, 85: F, 86: E, 87: D, 88: C, 89: B, 90: A, 91: , 92: , 93: , 94: , 95: , 96: , 97: z, 98: y, 99: x, 100: w, 101: v, 102: u, 103: t, 104: s, 105: r, 106: q, 107: p, 108: o, 109: n, 110: m, 111: l, 112: k, 113: j, 114: i, 115: h, 116: g, 117: f, 118: e, 119: d, 120: c, 121: b, 122: a, }
{0: , 1: , 2: , 3: , 4: , 5: , 6: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 14: , 15: , 16: , 17: , 18: , 19: , 20: , 21: , 22: , 23: , 24: , 25: , 26: , 27: , 28: , 29: , 30: , 31: , 32: , 33: , 34: , 35: , 36: , 37: , 38: , 39: , 40: , 41: , 42: , 43: , 44: , 45: , 46: , 47: , 48: , 49: , 50: , 51: , 52: , 53: , 54: , 55: , 56: , 57: , 58: , 59: , 60: , 61: , 62: , 63: , 64: , 65: Z, 66: Y, 67: X, 68: W, 69: V, 70: U, 71: T, 72: S, 73: R, 74: Q, 75: P, 76: O, 77: N, 78: M, 79: L, 80: K, 81: J, 82: I, 83: H, 84: G, 85: F, 86: E, 87: D, 88: C, 89: B, 90: A, 91: , 92: , 93: , 94: , 95: , 96: , 97: z, 98: y, 99: x, 100: w, 101: v, 102: u, 103: t, 104: s, 105: r, 106: q, 107: p, 108: o, 109: n, 110: m, 111: l, 112: k, 113: j, 114: i, 115: h, 116: g, 117: f, 118: e, 119: d, 120: c, 121: b, 122: a, }
当我尝试在文本文件上运行该程序时,(大多数)字符似乎映射到了它们的正确映射,但是也有很多垃圾,特别是在原始文本文件中的字符之间

原件:

For some reason, this program will not work.
程序输出:

Uli hln?I?Uv iv4M1zhlm?I?U, gs4M1rh k?I?Uilti??%1zn droo mlg dlip.
大多数字符似乎都已正确映射(“Uli hln”在原始文件中是“For som”,但随后出现一堆垃圾(?I?U),然后继续映射(在原始文件中v是e),依此类推


我已经盯着它看了几个小时了。有什么想法吗?

你的代码依赖于
strlen(format_str)
一开始就设置为全零。但是,没有
memset
。这就是随机的“垃圾”字符如何在“好”输出的字符中结束的

虽然
memset(format_str,0,sizeof(format_str))
可以解决这个问题,但是添加一个指针或一个您正在编写的索引会更好:

int j = 0;
...
format_str[j++] = c_r;
...
// After the loop is over, null-terminate the string:
format_str[j++] = '\0';

第一个问题是您的格式字符串不是以null结尾的。对于包含8个字符的字符串,循环从0到7。因此,您的第一个格式字符串[strlen(format\u str)]已经将数据放入随机内存,甚至可能是您的编码表。

strlen(format\u str)
产生不一致的值应该是您的问题;
memset
在您开始使用它之前,或者改用
i


此外,您的编码/解码数组大小为122,但根据您的数据包含123个元素;这是一个缓冲区溢出,可能会导致内存阻塞,导致意外行为。

format\u str[strlen(format\u str)]=c_r;
–似乎您希望
format_str
初始化为全零。它不是–它是未初始化的。而且
reset
是无用的(它是一个死写)。
如果(c==EOF){
c是一个字符。应该是一个int。(并且不需要与EOF进行比较,因为它已经用fgets()读入了,
if(c!=0)
永远不会失败,因为您在循环中使用
strlen()
,这将截断0处的行。这是内部循环中的三个
strlen()
调用。您知道这有多糟糕吗?还有,您重写
tr
有什么原因吗?谢谢。这非常有用。