C语言BUG?

软件和网站开发以及相关技术探讨
回复
flyinflash
帖子: 2376
注册时间: 2006-09-21 14:28

C语言BUG?

#1

帖子 flyinflash » 2008-03-21 12:25

下面的 getch 不用两次会“跳“过,是C本身的BUG,还是我写的代码有问题?

代码: 全选

// sequen store type of linear list
// 线性表顺序存储

// Last Modified: 2008-03-21

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 最大记录数
#define MAX_RECORDS 100

typedef struct
{
  // 名字最大长度为单位四
  char name[MAX_RECORDS][strlen("爱新觉罗")];
  // 表的长度
  int guys;
} student;


void clear_list(student *s)
{
  s->guys = 0;
}


void create_list(student *s)
{
  int guys, i;
  int bool_lock;

  bool_lock = 0;
  
  printf("\n");
  do
  {
    if (!bool_lock)
    {
      printf("\n 录入数据个数: ");
    } else {
      printf("\n 个数超出系统限制。请重新输入录入数据个数: ");
    }
    
    scanf("%d", &guys);
  
    bool_lock = 1;
  } while (guys > MAX_RECORDS);
  
  s->guys = guys;
  
  printf("\n  输入姓名 \n");
  for (i = 0; i < guys; i++)
  {
    printf("\n   姓名%d: ", i + 1);
    scanf("%s", s->name[i]);
  }
  
}


int insert_list(student *s)
{
  char tmp_name[strlen("爱新觉罗")];
  int tmp_pos;
  int bool_lock;
  int i;
  
  if (s->guys == MAX_RECORDS)
  {
    printf("\n");
    printf("\n 数据堆已满,请删除若干结点再插入 \n");
    printf("\n");
    printf("\n 按下回车继续 \n");
    getchar();
    getchar();
    return 0;
  }
  
  bool_lock = 0;
  
  printf("\n");
  printf("\n 输入插入姓名: ");
  scanf("%s", tmp_name);
  
  do
  {
    if (!bool_lock)
    {
      printf("\n");
      printf("\n 输入插入位置: ");
      scanf("%d", &tmp_pos);
    } else {
      printf("\n 位置不存在。请重新输入插入位置: ");
      scanf("%d", &tmp_pos);
    }
    bool_lock = 1;
    
  } while ( (tmp_pos > MAX_RECORDS + 1) || 
            (tmp_pos < 1) ||
            ((tmp_pos - s->guys) > 1)
            );
  
  for (i = s->guys; i >= (tmp_pos - 1); i--)
  {
    strcpy(s->name[i], s->name[i-1]);
  }
  strcpy(s->name[tmp_pos - 1], tmp_name);
  
  s->guys++;
  
  return 1;
}


int locate_list(student *s)
{
  char tmp_name[strlen("爱新觉罗")];
  int i;
  
  if (s->guys < 1)
  {
    printf("\n");
    printf("\n 数据堆为空,没有结点可搜索 \n");
    printf("\n");
    printf("\n 按下回车继续 \n");
    getchar();
    getchar();
    return 0;
  }
  
  printf("\n 根据结点的值搜索它的位置 \n");
  printf("\n 1表示第一个,2表示第二个,依此类推 \n");


  printf("\n");
  printf("\n 输入搜索结点的值: ");
  scanf("%s", tmp_name);
  
  for (i = 0; i < s->guys; i++)
  {
    if (strcmp(s->name[i], tmp_name) == 0)
      printf("\n 在位置%d \n", i+1);
  }
  
  printf("\n 按下回车继续 \n");
  getchar();
  getchar();
  
  return 1;
}


int modified_list(student *s)
{
  char tmp_name[strlen("爱新觉罗")];
  int tmp_pos;
  int bool_lock;
  
  if (s->guys < 1)
  {
    printf("\n");
    printf("\n 数据堆为空,没有结点可删除 \n");
    printf("\n");
    printf("\n 按下回车继续 \n");
    getchar();
    getchar();
    return 0;
  }
  
  printf("\n 修改结点 \n");
  printf("\n 1表示第一个,2表示第二个,依此类推 \n");
  
  bool_lock = 0;
  
  do
  {
    if (!bool_lock)
    {
      printf("\n");
      printf("\n 输入修改位置: ");
      scanf("%d", &tmp_pos);
    } else {
      printf("\n 位置不存在。请重新输入插入位置: ");
      scanf("%d", &tmp_pos);
    }
    bool_lock = 1;
    
  } while ( (tmp_pos > MAX_RECORDS + 1) || 
            (tmp_pos < 1)
            );
  
  printf("\n 旧姓名: %s", s->name[tmp_pos - 1]);
  
  printf("\n 输入新姓名: ");
  scanf("%s", tmp_name);
  
  strcpy(s->name[tmp_pos - 1], tmp_name);
  
  
  return 1;
}


int remove_list(student *s)
{
  int tmp_pos;
  int bool_lock;
  int i;
  
  if (s->guys == 0)
  {
    printf("\n");
    printf("\n 数据堆为空,没有结点可删除 \n");
    printf("\n");
    printf("\n 按下回车继续 \n");
    getchar();
    getchar();
    return 0;
  }
  
  bool_lock = 0;
  
  printf("\n 删除结点 \n");
  printf("\n 1表示第一个,2表示第二个,依此类推 \n");
  
  do
  {
    if (!bool_lock)
    {
      printf("\n 输入删除结点位置: ");
      scanf("%d", &tmp_pos);
    } else {
      printf("\n 位置不存在。请重新输入结点位置: ");
      scanf("%d", &tmp_pos);
    }
    
    bool_lock = 1;
  } while ( (tmp_pos > s->guys) || (tmp_pos < 1) );
  
  for (i = (tmp_pos - 1 ); i < (s->guys - 1); i++)
  {
    strcpy(s->name[i], s->name[i + 1]);
  }
  s->guys--;
  
  return 1;
}


void measure_list(student *s)
{
  printf("\n");
  printf("\n 共有%d条记录 \n", s->guys);
  
  printf("\n");
  printf("\n 按下回车继续 \n");
  getchar();
  getchar();
}


void print_list(student *s)
{
  int i;
  
  printf("\n");
  
  if (s->guys < 1)
  {
    printf("\n 共有0条记录 \n");

    printf("\n");
    printf("\n 按下回车继续 \n");
    getchar();
    getchar();
  } else {
    for (i = 0; i <= (s->guys - 1); i++)
    {
      printf("\n   %d: ", i + 1);
      printf("%s", s->name[i]);
    }
    
    printf("\n");
    printf("\n 按下回车继续 \n");
    getchar();
    getchar();
  }
  
}

int get_node_value(student *s)
{
  int tmp_pos;
  int bool_lock;
  
  if (s->guys == 0)
  {
    printf("\n");
    printf("\n 数据堆为空,没有结点可查询 \n");
    printf("\n");
    printf("\n 按下回车继续 \n");
    getchar();
    getchar();
    return 0;
  }
  
  printf("\n 查看 x 位置结点 \n");
  printf("\n 1表示第一个,2表示第二个,依此类推 \n");
  
  tmp_pos = 0;
  
  do
  {
    if (!bool_lock)
    {
      printf("\n 输入查询结点位置: ");
      scanf("%d", &tmp_pos);
    } else {
      printf("\n 位置不存在。请重新输入结点位置: ");
      scanf("%d", &tmp_pos);
    }
    
    bool_lock = 1;
  } while ( (tmp_pos > s->guys) || (tmp_pos < 1) );
  
  printf("\n");
  printf("\n 位置%d结点的值为: %s \n", tmp_pos, s->name[tmp_pos - 1]);
  
  printf("\n 按下回车继续 \n");
  getchar();
  getchar();
  
  return 1;
}

int main(int argc, char **argv)
{
  void create_list(student *s);
  int insert_list(student *s);
  int locate_list(student *s);
  int modified_list(student *s);
  int remove_list(student *s);
  void measure_list(student *s);
  void clear_list(student *s);
  void print_list(student *s);
  int get_node_value(student *s);
        
  char key[2];
  student *s;
  s = (student *)malloc(sizeof(student));
  // char name[MAX_RECORDS][strlen("爱新觉罗")];
  
  printf("\n");
  printf("\n    线性表的顺序存储示例 \n");
  create_list(s);
  print_list(s);
  
  do
  {
    fflush(stdin);
    printf("\n");
    printf("\n");
    printf("\n 1. 初始化|新建表 ");
    printf("\n 2. 清除 ");
    printf("\n 3. 长度 ");
    printf("\n");
    printf("\n 4. 插入 ");
    printf("\n 5. 删除 ");
    printf("\n 6. 修改 ");
    printf("\n");
    printf("\n 7. 查询 ");
    printf("\n 8. 搜索 ");
    printf("\n 9. 打印 ");
    printf("\n");
    
    printf("\n 0|q 退出 ");
    printf("\n");
    printf("\n   ");
    
    scanf("%2s", key);
    
    switch(key[0])
    {
      case '1':
        create_list(s);
        break;
        
      case '2':
        clear_list(s);
        break;
        
      case '3':
        measure_list(s);
        
        break;
      case '4':
        insert_list(s);
        
        break;
      case '5':
        remove_list(s);
        break;
        
      case '6':
        modified_list(s);
        break;
        
      case '7':
        get_node_value(s);
        break;
        
      case '8':
        locate_list(s);
        break;
        
      case '9':
        print_list(s);
        break;
        
      case 'q':
      case '0':
        goto QUIT_FLAG;
        
      default:
        printf("\n %2s:找不到命令 ", key);
        printf("\n");
        break;
    }
    
  } while ( (key[0] <= '9') && (key[0] > '0') );
  
  
  QUIT_FLAG:
  
  return 0;
  
}

/*

  char *tmp = "林毓琦";

  printf("\n");
  printf("  [debug] sizeof %d \n", sizeof(tmp));
  printf("  [debug] source %s \n", tmp);
  printf("  [debug] strlen %d ", strlen(tmp));

*/

代码: 全选

lee@lee-laptop:/home/share/project/GDCP/DS$ gcc -v
使用内建 specs。
目标:i486-linux-gnu
配置为:../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release i486-linux-gnu
线程模型:posix
gcc 版本 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
lee@lee-laptop:/home/share/project/GDCP/DS$ 
flyinflash
帖子: 2376
注册时间: 2006-09-21 14:28

#2

帖子 flyinflash » 2008-03-21 12:27

郁闷很久了,难道又是

代码: 全选

i++ i++ ++i
类型的问题?
头像
BigSnake.NET
帖子: 12522
注册时间: 2006-07-02 11:16
来自: 廣州
联系:

#3

帖子 BigSnake.NET » 2008-03-21 12:32

scanf 没吃掉回车?..
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。
flyinflash
帖子: 2376
注册时间: 2006-09-21 14:28

#4

帖子 flyinflash » 2008-03-21 12:43

骇人听闻的是:WINDOWS 下的活化石 TC 竟然没有这种问题。

还有,我想破脑袋也没有想明白,为什么 getch 没有收入 ANSI C。
头像
Yizer
帖子: 297
注册时间: 2007-11-07 14:41
来自: 佳木斯
联系:

#5

帖子 Yizer » 2008-03-21 13:27

格式问题吧
dev C++貌似没有问题
win下的换行是一个回车加上一个换行(ansii 13+10)
lin下的换行是一个换行符(ansii 13?10?是哪个我忘记了,好像是13)
Dell 1520
------------------------
Intel Core T7500
1G*2
120G
Nvidia 8600 GT
My BLOG
头像
monnand
帖子: 104
注册时间: 2007-02-16 1:23

#6

帖子 monnand » 2008-03-21 13:46

1 函数库的问题不是C语言的问题。函数库是函数库,它出了问题只是实现的问题。如果说C语言有问题,最多说它的某些语法不合理。
2 前面已经说了,其实是缓冲区处理的方式问题。你把buffer关掉试试看。
flyinflash
帖子: 2376
注册时间: 2006-09-21 14:28

#7

帖子 flyinflash » 2008-03-21 14:24

大哥,您都看到了,也该明白了——我是很笨的,请直接点告诉我改哪里吧!
回复