LinuxSir.cn,穿越时空的Linuxsir!

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

请各位来看看这个小程序出了什么问题

[复制链接]
发表于 2006-9-5 16:09:30 | 显示全部楼层 |阅读模式
这是一个书上的题目,我实现了一下,其实就是自己写一个more,程序在下面请各位帮忙看一下,我究竟错在哪里,我整整研究了一下午(初学Linux编程)没搞定。
#include <stdio.h>
#include <stdlib.h>

#define LINELEN 512
#define PAGELEN 24

void do_more(FILE *fp);
int see_more();

int main(int argc,char *argv[])
{
        FILE *fp;
        if(argc == 1){
                printf("%s\n","lease DON'T make a joke!!");
                exit(1);
        }
        fp = fopen(*++argv,"r");
        if(ferror(fp))
                exit(1);
        do_more(fp);
        fclose(fp);
        return 0;       
}

void do_more(FILE *fp)
{
        char *buf;
        int reply;
        int num_of_lines = 0;

        while(fgets(buf,LINELEN,fp)){
                if(num_of_lines < PAGELEN){
                        if(fputs(buf,stdout) == EOF)
                                exit(1);
                        num_of_lines++;
                }
                reply =        see_more();
                if(reply == 0)
                        exit(0);
                else if(reply == 1)
                        num_of_lines--;
                else if(reply == 2)
                        num_of_lines = 0;
        }
}

int see_more()
{
        int i;
        char c;
        printf("%s\n","more?[q,Space&Enter]");
        c = getchar();
        switch(c){
        case 'q':return 0;
        case ' ':return 1;
        case '\n':return 2;
        }
        return 0;
}
编译能通过,只是运行的时候就不行了。总是Segmentation fault。
发表于 2006-9-5 16:23:44 | 显示全部楼层
先排版一下,这样不是漂亮多了? 大家才有耐心帮你debug。
[php]
#include <stdio.h>
#include <stdlib.h>

#define LINELEN 512
#define PAGELEN 24

void do_more(FILE * fp);
int see_more();

int main(int argc, char *argv[])
{
        FILE *fp;
        if (argc == 1) {
                printf("%s\n", "lease DON'T make a joke!!");
                exit(1);
        }
        fp = fopen(*++argv, "r");
        if (ferror(fp))
                exit(1);
        do_more(fp);
        fclose(fp);
        return 0;
}

void do_more(FILE * fp)
{
        char *buf;
        int reply;
        int num_of_lines = 0;

        while (fgets(buf, LINELEN, fp)) {
                if (num_of_lines < PAGELEN) {
                        if (fputs(buf, stdout) == EOF)
                                exit(1);
                        num_of_lines++;
                }
                reply = see_more();
                if (reply == 0)
                        exit(0);
                else if (reply == 1)
                        num_of_lines--;
                else if (reply == 2)
                        num_of_lines = 0;
        }
}

int see_more()
{
        int i;
        char c;
        printf("%s\n", "more?[q,Space&Enter]");
        c = getchar();
        switch (c) {
        case 'q':
                return 0;
        case ' ':
                return 1;
        case '\n':
                return 2;
        }
        return 0;
}
[/php]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-9-5 16:25:40 | 显示全部楼层
......不会排版………我先还是研究一下如何排版吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-9-5 16:32:01 | 显示全部楼层
美女斑竹 能不能告诉一下在那有关于排版的帖子 我好研究一下 我找了一下 没找到 麻烦了
回复 支持 反对

使用道具 举报

发表于 2006-9-5 16:32:26 | 显示全部楼层
[php]
    while (fgets(buf, LINELEN, fp)) {
    ...
    }
[/php]
这里就错了。 buf只是一个char*,你又没有为它分配空间, 自然会segfault了。
回复 支持 反对

使用道具 举报

发表于 2006-9-5 16:35:05 | 显示全部楼层
Post by MooreChow
  能不能告诉一下在那有关于排版的帖子 我好研究一下 我找了一下 没找到 麻烦了
贴子排版可以用标签。比如 [ code ] 你的代码 [  /code ], 或者   [ php ] 你的代码 [  /php ]

如果是你自己的代码文件要排版,可以用相关排版缩进软件, 比如 indent。

ps: 不要从头像判断性别,闹笑话
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-9-5 16:47:29 | 显示全部楼层
谢谢斑竹指导,我把代码改了一下,结果可以运行了,虽然还是有其他的错误。
……
char buf[LINELEN];
……
这样就可以了,其实说白了还是我的C不过关,我根本没意识到我还没有分配空间给buf就开始用它了。
另外,斑竹你的头像和你的ID同时作用,恐怕很难让任何人在第一时间里做出正确的判断
……笑…

再试试看排版的效果

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define LINELEN 512
  4. #define PAGELEN 24

  5. void do_more(FILE *fp);
  6. int see_more();

  7. int main(int argc,char *argv[])
  8. {
  9.       FILE *fp;
  10.       if(argc == 1){
  11.       printf("%s\n","Please DON'T make a joke!!");
  12.       exit(1);
  13.       }
  14.       fp = fopen(*++argv,"r");
  15.       if(ferror(fp))
  16.      exit(1);
  17.      do_more(fp);
  18.      fclose(fp);
  19.      return 0;
  20. }
复制代码


[php]
void do_more(FILE *fp)
{
     char buf[LINELEN];
     int reply;
     int num_of_lines = 0;

     while(fgets(buf,LINELEN,fp)){
         if(num_of_lines < PAGELEN){
             if(fputs(buf,stdout) == EOF)
             num_of_lines++;
             exit(1);
         }
     reply = see_more();
     if(reply == 0)
         exit(0);
     else if(reply == 1)
         num_of_lines--;
     else if(reply == 2)
         num_of_lines = 0;
}
}

int see_more()
{
    int i;
    char c;
    printf("%s\n","more?[q,Space&Enter]");
    c = getchar();
    switch(c){
    case 'q':return 0;
    case ' ':return 1;
    case '\n':return 2;
   }
   return 0;
}

[/php]
回复 支持 反对

使用道具 举报

发表于 2006-9-5 16:51:00 | 显示全部楼层
标签只能保证你原来的代码版式不会在贴出后变动。也就是说你在敲代码时就要注意格式。
不过你还可以用indent这个软件用来对C文件自动排版(主要是缩进功能)。比如:
indent -kr -i8 myfile.c
回复 支持 反对

使用道具 举报

发表于 2006-9-5 19:55:27 | 显示全部楼层
版主的头像和id相结合,说明版主是个bt,hoh
回复 支持 反对

使用道具 举报

发表于 2006-9-8 17:29:05 | 显示全部楼层
Post by x11
版主的头像和id相结合,说明版主是个bt,hoh

x11兄的生活过得很滋润嘛!
回复 支持 反对

使用道具 举报

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

本版积分规则

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