如果声明char finalstr[2048];
,以下代码将正确打印到文件中,但是如果我删除它(因为它没有在任何地方使用(,程序会打印垃圾ASCII。这让我相信这与记忆有关,但我一无所知。
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
FILE *fp2;
char str[2048];
char finalstr[2048];
fp = fopen("f_in.txt", "r");
fp2 = fopen("f_out.txt", "w");
while(fgets(str,2047,fp))//read line by line until end of file
{
int i;
for(i=0;i<=strlen(str);i++)//go trough the string cell by cell
{
if(str[i]>47 && str[i]<58 && str[i+1]>47 && str[i+1]<58)//from 0 to 9
{
char temp[2];//to hold temporary two digit string number
temp[0]=str[i];
i++;
temp[1]=str[i];
if(atoi(temp)<27)//if it's an upper case letter
fprintf(fp2,"%c",atoi(temp)+64);
else//if it's lowercase, skip the special characters between Z and a
fprintf(fp2,"%c",atoi(temp)+70);
}
else fprintf(fp2,"%c",str[i]);
}
}
fclose(fp);
fclose(fp2);
}
输入
20343545 3545 27 494140303144324738 343150 404739283144: ffabcd. 094540' 46 3546?
01404146343144 283127474635324738 404739283144 09 453131 3545 abcdefYXWVUTSRQP
2044474546 3931. 09 37404149 27 384146!
声明finalstr[]
时的输出
This is a wonderful hex number: ffabcd. Isn' t it?
Another beautiful number I see is abcdefYXWVUTSRQP
Trust me. I know a lot!
未声明finalstr[]
时的输出
?99? 9? 9 ?9999?9?9 99? 9?999?: ffabcd. ??9' ? 9??
((((.(( (((((.((. ((.((( ( ((( .( abcdefYXWVUTSRQP
øòòøò øò. ø òòòò ø òòò!
我确实注意到第一个if()
语句可能会导致溢出,但是用<
替换<=
对最终结果没有影响。
我真的想知道这背后的解释是什么,它是否特定于 C 语言,或者它是否也会发生在C++。
主要问题在于您使用的临时字符串。 它不够长,无法存储 null 终止字符,因此您有一个未终止的字符串。
使数组长度为 3 个字节并添加终止符:
char temp[3];//to hold temporary two digit string number
temp[0]=str[i];
i++;
temp[1]=str[i];
temp[2]=0;
此外,您在for
循环中看起来离数组末端太远。 使用<
而不是<=
:
for(i=0;i<strlen(str);i++)//go trough the string cell by cell
最后,确保您#include <string.h>
,以便您有一个正确的strlen
声明。
atoi(temp)
会导致未定义的行为。atoi
函数需要一个指向以 null 结尾的字符串的指针作为参数,但是您提供了指向两个没有终止符的字符的指针。
atoi
函数将读取数组的末尾。您的虚拟数组会影响这一点,因为它会更改temp
数组之后存在的垃圾。
顺便说一句,您可以使用(str[i] - '0') * 10 + (str[i+1] - '0')
而不是atoi
.
据我了解,问题在于程序通过以下方式填充数组,使其可能达到其全部容量
fgets(str,2047,fp)
这意味着条件
i <= strlen(str)
仅当 str
后的位置以零结尾时,才按预期工作;声明finalstr.
时可能就是这种情况