程序仅在声明虚拟字符数组 [C] 时才有效



如果声明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.时可能就是这种情况

最新更新