输出烫烫烫问题。。。。。。

qinglongjiao11 2011-04-03 12:23:35
输出烫烫烫问题。。。。。。在vc++6.0和c-free编译是有问题,在win-tc下没问题

代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
FILE *fp;
char string[80];
int i=0;
if((fp=fopen("E:\\音乐\\succeed.txt","w"))==NULL)
{
printf("can't open file");
exit(1);
}
while((string[i]=getchar())!='!')
{if(string[i]>='a'&&string[i]<='z') string[i]=string[i]-32;
i++;}
fputs(string,fp);
fputs("\n",fp);
fclose(fp);
return 0;
}
就是输出地文件内容末尾出现了很多个“烫”,还有几个奇怪的字符。。那

个零怎么不会被输出呢?跟内存有关系吗?
...全文
178 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
qinglongjiao11 2011-04-03
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 tandyt 的回复:]
写文件函数 fputs 将指定的字符串写入到文件中,写的时候会检测字符串终止符 '\0',如果
遇到了字符串终止符,fputs 就完成了写入工作, fputs 不会写入字符串终止符,原因是
fputs 认为字符串终止符并不是字符串数据的有意义的组成部分。就好比打电话,说了一大堆
话,最后说“再见”,然后双方挂电话,打电话的双方关心的是前面说的内容,最后说的“再
见”不是谈话内容有意义的组……
[/Quote]

新手,想先用好 VC6 ,来学基础知识
TandyT 2011-04-03
  • 打赏
  • 举报
回复
写文件函数 fputs 将指定的字符串写入到文件中,写的时候会检测字符串终止符 '\0',如果
遇到了字符串终止符,fputs 就完成了写入工作, fputs 不会写入字符串终止符,原因是
fputs 认为字符串终止符并不是字符串数据的有意义的组成部分。就好比打电话,说了一大堆
话,最后说“再见”,然后双方挂电话,打电话的双方关心的是前面说的内容,最后说的“再
见”不是谈话内容有意义的组成部分,仅仅是礼仪性的标志着双方应该结束通话。
对于txt文件而言,我们可以自己手动写入'\0',但这种写入一般是没有意义的,打开txt文件
,看不到这个'\0'。就如同楼主后面一个 fputs("\n", fp),可加可不加。如果仅仅是为了在
txt文件中产生一个换行符的话,\n 是不够的,必须输出 \r\n ,即 fputs("\r\n", fp);
另外,楼主的程序存在着一个严重的BUG,即缓冲区溢出问题!
楼主只分配了80个字节的缓冲区 string ,如果 getchar 一直接收不到 "!" ,getchar 80个
字节后就会溢出。因此,正确的代码逻辑需要循环体的某处或while 条件中加上 i 的判断:

while (((string[i] = getchar()) != '!')) { ... ;if (i >= 79) break;...} string[i] =

'\0';

楼主如果是在公司里做,一般写好的代码由测试员负责测试,如果定的标准是10000行代码允许

的BUG是5个,当测试员测试了1000行代码,就发现了5个BUG,那么对不起,测试员会把代码退

回给楼主,楼主你自己先找BUG吧,测试员不负责了。
一般,严格的公司 BUG 是3~5个/10000行。

看楼主的全是标准 C 代码,可能还不知道缓冲区溢出的厉害,楼主可以记住,自己定义的缓冲区,一定要检查是否会越界,越界了就是溢出了。至于溢出的危害性,等代码写多了,功力深了,自然明白了。
那个“烫”的原因:
正如一楼指出的,楼主没有显示为string设置字符串终止符,导致 fputs 写入到txt中时,由

于一直无法在string中找到字符串终止符,因此将"!"之后无用的数据全部也写入到了txt中。

好习惯是,对定义的变量先初始化,然后使用,这样有利于调试,错误查找,甚至是避免潜在

的错误。
初始化:
FILE *fp = NULL;
char string[80] = { 0 };//不需要像StudyBoyG那样复杂的初始化语法:memset(string, 0,

sizeof(char)*80);

VC的编译器,在DEBUG模式下编译源代码时,会将我们指定分配的堆栈内存字节初始化为0xcc。
如char string[80],这80个字节会被初始化为0xcc,楼主可以将光标定位到int i = 0;然后按
F9设一个断点,按F5调试运行,命中断点后,在“调试”菜单中选择“内存”子菜单项,在弹
出的内存窗口中,在地址栏输入 string 回车,楼主可以验证一下,这80个字节都是什么内容


fputs由于把0xcc写入到了txt中,当打开txt,就会看到0xcc代表的中文字符“烫”。VC编译器

初始化内存为0xcc,就是为了便于我们发现错误,进行调试用的。因此相对TC而言,楼主认为

哪个更好呢?

P.S.如果用VC的话,稍微习惯了VC后,把6.0扔了吧,换个VS2008,VS2010什么的,上手VS,肯

定会很痛苦,但 “工欲善其事必先利其器”,6.0都是十几年前的老古董了。而它们之间的区

别,也差远了。并不像很多人说的那样,6.0怎么怎么好。

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧