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

时间:2016-02-15 13:09:01

标签: 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 ++中发生。

3 个答案:

答案 0 :(得分:2)

主要问题在于您使用的临时字符串。存储空终止字符的时间不够长,因此您有一个未终止的字符串。

使数组长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的正确声明。

答案 1 :(得分:1)

atoi(temp)导致未定义的行为。 atoi函数需要一个指向以null结尾的字符串作为参数的指针,但是您提供了指向两个不带终结符的字符的指针。

atoi函数将读取数组的结尾。您的虚拟数组会影响这一点,因为它会更改temp数组后的垃圾。

顺便说一句,您可以使用(str[i] - '0') * 10 + (str[i+1] - '0')代替atoi

答案 2 :(得分:0)

根据我的理解,问题在于程序可能会通过

填充数组
i <= strlen(str)

表示条件

str
仅当finalstr.之后的位置以零结尾时,

才能正常工作;声明C

时可能就是这种情况