fgets在循环中使用出错?!
2016-07-14 14:30
387 查看
fgets在循环中使用出错?!
是的,我今天在做程序时,就遭遇了这个问题,严格上来说,这是一个与指针有关的问题。先看看下述代码段:
#define LINE_LENGTH 100
void import_file(char* file_path)
{
int sum = 0;
FILE *fp_r;
FILE *fp_w;
char *line;//[LINE_LENGTH];
int i=0;
char ch;
if((fp_r=fopen(file_path,"r"))==NULL)
{
printf("can not open file!\n");
return; // exit(0);
}
if((fp_w=fopen("result.txt","w"))==NULL)
{
printf("error:can not find result.txt!\n");
return; // exit(0);
}
while(!feof(fp_r))
{
if(fgets(line,LINE_LENGTH,fp_r)!=NULL);
//count(line);
fprintf(fp_w,"%s\n",line);
}
fclose(fp_r);
fclose(fp_w);
printf("write file ok!\n");
}
//或许你会觉得这样写不会出错,当然,我也是这样认为的。可是编译器却不这样认为,它在运行时会出错。
一开始我以为是编译器坏了,于是跑去其他同学那里测试,发现问题依旧。值得一提的是我跟他用的是不同类型的编译器。
想了很久,最后终于想到把char *line;改为char line[LINE_LENGTH];,结果就行了,当时我认为可能是line用指针类型无法确定其长度的缘故。
不过我记得之前我的代码曾经有段时间那样写不会出错啊!
持着怀疑的态度,我又把代码改了回去,奇怪的事情发生了,没问题了!?可以正常运行了!
难道是编译器的漏洞,郁闷啊!害我忙活了那么久。这什么世道啊!这种事情也要我来弄!
最后顺便补充点东西,大家很容易搞混的:
在字符串里面,'\n'是换行符,它并不代表一个字符串的结束,而是由'\0'来代表,至于EOF,它是一个int型的特殊符号,代表文件内容的结束,要用feof()来判断。还有NULL,这个代表无内容,
它们这几者之间有区别吗?有!所以大家写程序时千万要小心,要区分对待!
后记:晚上回到家里,正好U盘里有旧文件,我又拿出来重新调试了一边,终于找到真正的原因了。
原来是我在另一个函数里使用指针的问题:
int count(char *word)
{
int sum=0;
unsigned int i=0;
char *p=word;//
while(i<strlen(word))//word:一个单词。
{
///if(*p=='\n')
//break;
sum+=(*p)-64;
i++;
p++;
//if(*p=='\0')
//break;
}
return sum;
}
在如上代码中,两处被注释掉的语句,任意去掉一处都能保证正常运行,关键点是在p指针那里,一旦加的时候超出了原先的字符串的范围,就会出错,其特征就是运行框return 一个没规律的大数,有可能是负值。回到代码可以发现,实际上输入的字符串是来自文件,它是按行读取的,word字符串的结尾处先是'\n',后是'\0','\n'是fgets读到的,'\0'是fgets自己加上去的,假设字符串实际长度为L(包含换行符),strlen不计'\0',那么由于i是从0开始加的,从0到L-1,一共L个字符,在i=L-1时p++,那么p将指向'\0',难道是因为这个出错,一旦指向这里就会出错?从实际情况的反映来看,确实如此。如果真的是这样,那么就算char
*line所指向的字符串不知道其长度,只要保证p不要越界就行了,不过就算这样来看,还是觉得有点奇怪,难道strlen不起作用了?居然需要另外添加跳出语句。好了,就说这多。
还有点东西,转载来的,不知道放不放的下
http://www.programfan.com/club/showtxt.asp?id=106212
您所在位置:编程爱好者网站 — 编程爱好者论坛 —
[转帖]用程序证明 NULL '\0' 0 的不同
原帖地址:http://bbs.pfan.cn/post-106212.html
主题:[转帖]用程序证明 NULL '\0' 0 的不同
收藏于 2009-12-05
是的,我今天在做程序时,就遭遇了这个问题,严格上来说,这是一个与指针有关的问题。先看看下述代码段:
#define LINE_LENGTH 100
void import_file(char* file_path)
{
int sum = 0;
FILE *fp_r;
FILE *fp_w;
char *line;//[LINE_LENGTH];
int i=0;
char ch;
if((fp_r=fopen(file_path,"r"))==NULL)
{
printf("can not open file!\n");
return; // exit(0);
}
if((fp_w=fopen("result.txt","w"))==NULL)
{
printf("error:can not find result.txt!\n");
return; // exit(0);
}
while(!feof(fp_r))
{
if(fgets(line,LINE_LENGTH,fp_r)!=NULL);
//count(line);
fprintf(fp_w,"%s\n",line);
}
fclose(fp_r);
fclose(fp_w);
printf("write file ok!\n");
}
//或许你会觉得这样写不会出错,当然,我也是这样认为的。可是编译器却不这样认为,它在运行时会出错。
一开始我以为是编译器坏了,于是跑去其他同学那里测试,发现问题依旧。值得一提的是我跟他用的是不同类型的编译器。
想了很久,最后终于想到把char *line;改为char line[LINE_LENGTH];,结果就行了,当时我认为可能是line用指针类型无法确定其长度的缘故。
不过我记得之前我的代码曾经有段时间那样写不会出错啊!
持着怀疑的态度,我又把代码改了回去,奇怪的事情发生了,没问题了!?可以正常运行了!
难道是编译器的漏洞,郁闷啊!害我忙活了那么久。这什么世道啊!这种事情也要我来弄!
最后顺便补充点东西,大家很容易搞混的:
在字符串里面,'\n'是换行符,它并不代表一个字符串的结束,而是由'\0'来代表,至于EOF,它是一个int型的特殊符号,代表文件内容的结束,要用feof()来判断。还有NULL,这个代表无内容,
它们这几者之间有区别吗?有!所以大家写程序时千万要小心,要区分对待!
后记:晚上回到家里,正好U盘里有旧文件,我又拿出来重新调试了一边,终于找到真正的原因了。
原来是我在另一个函数里使用指针的问题:
int count(char *word)
{
int sum=0;
unsigned int i=0;
char *p=word;//
while(i<strlen(word))//word:一个单词。
{
///if(*p=='\n')
//break;
sum+=(*p)-64;
i++;
p++;
//if(*p=='\0')
//break;
}
return sum;
}
在如上代码中,两处被注释掉的语句,任意去掉一处都能保证正常运行,关键点是在p指针那里,一旦加的时候超出了原先的字符串的范围,就会出错,其特征就是运行框return 一个没规律的大数,有可能是负值。回到代码可以发现,实际上输入的字符串是来自文件,它是按行读取的,word字符串的结尾处先是'\n',后是'\0','\n'是fgets读到的,'\0'是fgets自己加上去的,假设字符串实际长度为L(包含换行符),strlen不计'\0',那么由于i是从0开始加的,从0到L-1,一共L个字符,在i=L-1时p++,那么p将指向'\0',难道是因为这个出错,一旦指向这里就会出错?从实际情况的反映来看,确实如此。如果真的是这样,那么就算char
*line所指向的字符串不知道其长度,只要保证p不要越界就行了,不过就算这样来看,还是觉得有点奇怪,难道strlen不起作用了?居然需要另外添加跳出语句。好了,就说这多。
还有点东西,转载来的,不知道放不放的下
http://www.programfan.com/club/showtxt.asp?id=106212
您所在位置:编程爱好者网站 — 编程爱好者论坛 —
[转帖]用程序证明 NULL '\0' 0 的不同
原帖地址:http://bbs.pfan.cn/post-106212.html
主题:[转帖]用程序证明 NULL '\0' 0 的不同
收藏于 2009-12-05
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 关于指针的一些事情
- 如何写好 C main 函数
- Lua和C语言的交互详解
- C# Pointer指针应用实例简述
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C和指针小结(推荐)
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- C语言练习题:自由落体的小球简单实例
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- C语言中进制知识汇总
- C语言判断一个数是否是2的幂次方或4的幂次方