LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1446|回复: 12

为什么出现段错误呢?请指点一下好吗?

[复制链接]
发表于 2007-2-25 22:41:40 | 显示全部楼层 |阅读模式
[php]
#include <stdio.h>
int main()
{
        FILE *fp;
        char p[256];
        int c;

        if ((fp = fopen("m.txt", "r")) == NULL)
        {
                printf("打开文件失败!\n");
        }
        while (!feof(fp))
        {
                sprintf(p, "");
                while (((c = fgetc(fp)) != '\n') && (c !=-1))
                        sprintf(p, "%s%c", p, c);
        }
        fclose(fp);
        return 0;
}
[/php]
如题,想读取文件的一行。在这里如果把代码中的c!=-1换成c!=''\r''之类,就会出现段错误。可以指点下为什么吗?
发表于 2007-2-26 00:07:08 | 显示全部楼层
因为你在 c=fgetc(fp) 时没有检查 c 是不是 EOF。
回复 支持 反对

使用道具 举报

发表于 2007-2-26 11:47:45 | 显示全部楼层
Post by ytaome
[php]
#include <stdio.h>
int main()
{
        FILE *fp;
        char p[256];
        int c;

        if ((fp = fopen("m.txt", "r")) == NULL)
        {
                printf("打开文件失败!\n");
        }
        while (!feof(fp))
        {
                sprintf(p, "");
                while (((c = fgetc(fp)) != '\n') && (c !=-1))
                        sprintf(p, "%s%c", p, c);
        }
        fclose(fp);
        return 0;
}
[/php]
如题,想读取文件的一行。在这里如果把代码中的c!=-1换成c!=''\r''之类,就会出现段错误。可以指点下为什么吗?

这个程序很多问题,首先第一个if判断文件打开失败应该return,否则下面会使用空指针;sprintf(p, "")是干什么,初始化p为空吗,这种写法不好,有点莫名其妙,不如p[0] = '\0',或者strcpy(p, "")来得直接;c!=''\r'',双引号可以编译通过吗,字符如何和字符串比较;fgetc的返回值请参看函数说明,如下;内循环while也是,要获取一行,不如fgets好,你这样处理效率也太低了吧。

fgetc and _fgetchar return the character read as an int or return EOF to indicate an error or end of file.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-2-26 13:10:11 | 显示全部楼层
谢谢上面两位老师呀!
第一个判断之后应该直接return的.
第二个我是想给p初始化一下呵呵。看起来strcpy好像不错.p[0]='\0'是什么意思呢?长度为1而没有数值了?
那个双引号就纯粹是笔误了.我写成'\r'也不行.
fgetc没有用过,回去后好好看看说明嘿嘿.
二楼兄弟说没有检查EOF,可是我在while里面不是检查了吗?
回复 支持 反对

使用道具 举报

发表于 2007-2-26 14:31:22 | 显示全部楼层
Post by ytaome
谢谢上面两位老师呀!
第一个判断之后应该直接return的.
第二个我是想给p初始化一下呵呵。看起来strcpy好像不错.p[0]='\0'是什么意思呢?长度为1而没有数值了?
那个双引号就纯粹是笔误了.我写成'\r'也不行.
fgetc没有用过,回去后好好看看说明嘿嘿.
二楼兄弟说没有检查EOF,可是我在while里面不是检查了吗?

因为字符串是以'\0'结尾的,如果首字符就是这个,那么字符串就是空串。
二楼说你没有检查EOF,while里面检查你是说feof?他说的是里面那个while,你是用c != -1比较,这个-1啥意思?所以我说查一下fgetc这个函数的返回值。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-2-26 15:28:29 | 显示全部楼层
请问:feof()之后指向文件位置的指针会发生变化吗?如果指针不移动的话,就没有必要再检查一次了吧?
回复 支持 反对

使用道具 举报

发表于 2007-2-26 16:04:22 | 显示全部楼层
Post by ytaome
请问:feof()之后指向文件位置的指针会发生变化吗?如果指针不移动的话,就没有必要再检查一次了吧?

feof是不会改变文件指针,但是你里面的循环有fgetc会改变(循环也许不只执行一次),所以要判断。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-2-26 23:00:13 | 显示全部楼层
Post by xiexiecn
这个程序很多问题,首先第一个if判断文件打开失败应该return,否则下面会使用空指针;sprintf(p, "")是干什么,初始化p为空吗,这种写法不好,有点莫名其妙,不如p[0] = '\0',或者strcpy(p, "")来得直接;c!=''\r'',双引号可以编译通过吗,字符如何和字符串比较;fgetc的返回值请参看函数说明,如下;内循环while也是,要获取一行,不如fgets好,你这样处理效率也太低了吧。

fgetc and _fgetchar return the character read as an int or return EOF to indicate an error or end of file.

贴上fgets函数看看吧,没有用过呢
fgets(由文件中读取一字符串)
相关函数
        open,fread,fscanf,getc
表头文件
        include<stdio.h>
定义函数
        har * fgets(char * s,int size,FILE * stream);
函数说明
        fgets()用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行字符、读到文件尾或是已读了size-1个字符为止,最后会加上NULL作为字符串结束。
返回值
        gets()若成功则返回s指针,返回NULL则表示有错误发生。
范例
[php]
#include<stdio.h>
main()
{
char s[80];
fputs(fgets(s,80,stdin),stdout);
}
[/php]
执行
        this is a test /*输入*/
this is a test /*输出*/
顺便贴下我改正后的部分:
[php]
#include <stdio.h>
int main()
{
        FILE *fp;
        char p[256];
        int c;

        if ((fp = fopen("m.txt", "r")) == NULL)
        {
                printf("打开文件失败!\n");
                return 0;
        }
        while (!feof(fp))
        {
                strcpy(p,"");
                fgets(p,256,fp);
                printf("p=%s", p);
        }
        fclose(fp);
        return 0;
}
[/php]
还想问下,p要赋初值吗?strcpy(p,"");就可以了吗?
如果是: char *p;行不行呢?怎样赋初值呢?
回复 支持 反对

使用道具 举报

发表于 2007-2-27 08:38:07 | 显示全部楼层
这个我也插一嘴
对于数组的初始化strcpy(),应该是可以了
如果是char *p的话,他的初始化我感觉根string的差不多可以直接
char *p = "";
回复 支持 反对

使用道具 举报

发表于 2007-2-27 12:31:03 | 显示全部楼层
对,我是指你第二个while里没有检查EOF。  我觉得你的程序有段错误是因为在文件已经读完,但第二个while里的fgetc()还在运行。

你改之后的程序: p 没有必要赋予初值。strcpy(p,"")可以赋予p初值,char *p 也可以。其实char p[]和char *p 中的p是同一个类型(type)。

个人感觉如果是清空一个char array的话,p[0] = '\0'就可以了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表