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
有什么原因吗?谢谢。这非常有用。