当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 14 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 悬赏 50 人民币求 C 语言基础习题解
帖子发表于 : 2008-04-25 18:54 
头像

注册: 2006-09-21 14:28
帖子: 2376
送出感谢: 0 次
接收感谢: 0 次
1、
修正以下漏洞:
1、逃过 continue
2、主菜单按 enter 导致退出程序

确保上面源代码能通过 TC 2.0~3.0、 MVC++ 6.0、GCC 3.4~4.1 编译,并且无错、无警告

2、
解释导致上面漏洞出现的原因


代码:
// line structure
// sequential storage form

// Last Modified: 2008-03-21
// Last Modified: 2008-04-24

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

#define LIST_MAX_SIZE 5

typedef struct
{
  char data[LIST_MAX_SIZE];
  int length;
} data_obj;


void init(data_obj *d)
{
  d->length = 0;
  printf("\n");
  printf("\n init list ");
  printf("\n d->length = %d ", d->length);
 
  printf("\n");
  printf("\n continue ");
  getchar();
}
// tO(1)


void destory(data_obj *d)
{
  d->length = 0;
  printf("\n");
  printf("\n destory list ");
 
  printf("\n");
  printf("\n continue ");
  getchar();
}
// tO(1)


int insert(data_obj *d, char val, int pos)
{
  int i = 0;
 
  if (d->length == LIST_MAX_SIZE)
  {
    printf("\n");
    printf("\n  no space ");
    return 0;
  }
  if ( (pos < 1) || ((pos - d->length) > 1) )
  {
    printf("\n");
    printf("\n  error position ");
    getchar();
    return 0;
  }
  for (i = d->length; i >= pos; i--)
  {
    d->data[i] = d->data[i - 1];
  }
  d->data[pos - 1] = val;
  d->length++; 
 
  printf("\n");
  printf("\n continue ");
  getchar();
 
  return 1;
}
 

void print(data_obj *d)
{
  int i;
 
  if (d->length)
  {
    printf("\n");
    for (i = 0; i < d->length; i++)
    {
      printf("\n   %d: ", i + 1);
      printf("%c", d->data[i]);
    }
  }
  else
  {
    printf("\n");
    printf("\n no record \n");
  }
 
  printf("\n");
  printf("\n continue ");
  getchar();
  getchar();
}


int main()
{
  void init(data_obj *d);
  void destory(data_obj *d);
 
  int insert(data_obj *d, char val, int pos);
  /*
  int remove(data_obj *d);
  void locate(data_obj *d);
  */
  void print(data_obj *d);
       
  char key;
  char value;
  int position;
 
  data_obj *d;
  d = (data_obj *)malloc(sizeof(data_obj));
 
  printf("\n");
  printf("\n  line structure - sequential storage form ");
 
  init(d);
 
  do
  {
    printf("\n");
    printf("\n 1. init ");
    printf("\n 2. destory ");
    printf("\n");
   
    printf("\n 3. insert ");
    /*
    printf("\n 4. remove ");
    printf("\n 5. locate ");
    printf("\n");
    */
    printf("\n 6. print ");
    printf("\n");
   
    printf("\n 0|q quit ");
    printf("\n");
    printf("\n   ");
   
    scanf("%c", &key);
   
    switch(key)
    {
      case '1':
        printf("\n");
        init(d);
        break;
       
      case '2':
        destory(d);
        break;
       
      case '3':
        printf("\n");
        printf("\n insert value: ");
        getchar();
        scanf("%c", &value);
        printf("\n insert position: ");
        scanf("%d", &position);
        insert(d, value, position);
        break;
       
     /*
      case '4':
        remove(s);
        break;
       
      case '5':
        locate(s);
        break;
     */
      case '6':
        print(d);
        break;
       
      case '0':
        goto QUIT_FLAG;
    }
   
  } while ((key <= '9') && (key >= '0'));
 
 
  QUIT_FLAG:
 
  return 0;
 
}


_________________
http://lee.youxu.info/


页首
 用户资料  
 
2 楼 
 文章标题 :
帖子发表于 : 2008-04-25 19:07 
头像

注册: 2007-05-06 2:46
帖子: 15634
送出感谢: 0 次
接收感谢: 2
50 人民币

:em14

楼主没见过人民币

:em23


页首
 用户资料  
 
3 楼 
 文章标题 :
帖子发表于 : 2008-04-25 19:31 
头像

注册: 2006-05-03 0:39
帖子: 8273
地址: المريخ
送出感谢: 0 次
接收感谢: 1
代码:
// line structure
// sequential storage form

// Last Modified: 2008-03-21
// Last Modified: 2008-04-24

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

#define LIST_MAX_SIZE 5

typedef struct
{
  char data[LIST_MAX_SIZE];
  int length;
} data_obj;


void init(data_obj *d)
{
  d->length = 0;
  printf("\n");
  printf("\n init list ");
  printf("\n d->length = %d ", d->length);
 
  printf("\n");
//  printf("\n continue "); <-- 注释掉就没有了,估计你原有的程序可以在所有你所说的东西上编译通过,假设这是真的,那么我就可以用这种注释方式了
  getchar();
}
// tO(1)


void destory(data_obj *d)
{
  d->length = 0;
  printf("\n");
  printf("\n destory list ");
 
  printf("\n");
//  printf("\n continue ");
  getchar();
}
// tO(1)


int insert(data_obj *d, char val, int pos)
{
  int i = 0;
 
  if (d->length == LIST_MAX_SIZE)
  {
    printf("\n");
    printf("\n  no space ");
    return 0;
  }
  if ( (pos < 1) || ((pos - d->length) > 1) )
  {
    printf("\n");
    printf("\n  error position ");
    getchar();
    return 0;
  }
  for (i = d->length; i >= pos; i--)
  {
    d->data[i] = d->data[i - 1];
  }
  d->data[pos - 1] = val;
  d->length++; 
 
  printf("\n");
//  printf("\n continue ");
  getchar();
 
  return 1;
}
 

void print(data_obj *d)
{
  int i;
 
  if (d->length)
  {
    printf("\n");
    for (i = 0; i < d->length; i++)
    {
      printf("\n   %d: ", i + 1);
      printf("%c", d->data[i]);
    }
  }
  else
  {
    printf("\n");
    printf("\n no record \n");
  }
 
  printf("\n");
//  printf("\n continue ");
  getchar();
  getchar();
}


int main()
{
  void init(data_obj *d);
  void destory(data_obj *d);
 
  int insert(data_obj *d, char val, int pos);
  /*
  int remove(data_obj *d);
  void locate(data_obj *d);
  */
  void print(data_obj *d);
       
  char key;
  char value;
  int position;
 
  data_obj *d;
  d = (data_obj *)malloc(sizeof(data_obj));
 
  printf("\n");
  printf("\n  line structure - sequential storage form ");
 
  init(d);
 
  while ( 1 )
  {
    printf("\n");
    printf("\n 1. init ");
    printf("\n 2. destory ");
    printf("\n");
   
    printf("\n 3. insert ");
    /*
    printf("\n 4. remove ");
    printf("\n 5. locate ");
    printf("\n");
    */
    printf("\n 6. print ");
    printf("\n");
   
    printf("\n 0|q quit ");
    printf("\n");
    printf("\n   ");
   
    scanf("%c", &key);
   
    switch(key)
    {
      case '1':
        printf("\n");
        init(d);
        break;
       
      case '2':
        destory(d);
        break;
       
      case '3':
        printf("\n");
        printf("\n insert value: ");
        getchar();
        scanf("%c", &value);
        printf("\n insert position: ");
        scanf("%d", &position);
        insert(d, value, position);
        break;
       
     /*
      case '4':
        remove(s);
        break;
       
      case '5':
        locate(s);
        break;
     */
      case '6':
        print(d);
        break;
       
      case '0':
        goto QUIT_FLAG;
    }
   
  } /* 你原来的一按回车就条件不满足了 */
 
 
  QUIT_FLAG:
 
  return 0;
 
}


_________________
PHP是最好的语言!不服来战!


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 悬赏 50 人民币求 C 语言基础习题解
帖子发表于 : 2008-04-26 8:13 
头像

注册: 2007-07-12 16:30
帖子: 303
地址: 桂林
送出感谢: 0 次
接收感谢: 2
flyinflash 写道:
确保上面源代码能通过 TC 2.0~3.0、 MVC++ 6.0、GCC 3.4~4.1 编译,并且无错、无警告


不是谁都愿意为了几个编译工具去装这么多东东,要求GCC就够了。 :em14


页首
 用户资料  
 
5 楼 
 文章标题 :
帖子发表于 : 2008-04-26 15:47 
头像

注册: 2006-09-21 14:28
帖子: 2376
送出感谢: 0 次
接收感谢: 0 次
我要保留 continue 呢?

为什么有就会出问题?请 stlxv 回答要点



我更改了一下,加上若干个 getchar ——连用几个,“似乎”能比较人性化了,但是,觉得这样写冗余了。

嗯,正想请教一下 RMS


_________________
http://lee.youxu.info/


页首
 用户资料  
 
6 楼 
 文章标题 :
帖子发表于 : 2008-04-26 19:50 
头像

注册: 2008-02-18 0:25
帖子: 424
送出感谢: 0 次
接收感谢: 0 次
跳过continue是因为执行
代码:
scanf("%c", &key);

以后, 输入了一个回车, 传递给了init()函数中的getchar()函数, 可以改成
代码:
scanf("%c", &key);
getchar();

按Enter退出是因为不满足do~while的循环条件, 可以改成
代码:
do
{
  ...
}
while ((key != 'q') && (key != 'Q'));

我这里没有TC和VC, 抱歉不能测试, GCC通过.


_________________
图片


页首
 用户资料  
 
7 楼 
 文章标题 : Re: 悬赏 50 人民币求 C 语言基础习题解
帖子发表于 : 2008-04-27 9:28 
头像

注册: 2005-09-27 18:24
帖子: 498
地址: 杭州
送出感谢: 0 次
接收感谢: 0 次
flyinflash 写道:
1、
修正以下漏洞:
1、逃过 continue
2、主菜单按 enter 导致退出程序

确保上面源代码能通过 TC 2.0~3.0、 MVC++ 6.0、GCC 3.4~4.1 编译,并且无错、无警告


tc这个太令人发指了,谁还有阿。
vc 6不免费,没装 不过还是学生,vs2008倒是可以免费用 呵呵


页首
 用户资料  
 
8 楼 
 文章标题 :
帖子发表于 : 2008-04-28 17:52 
头像

注册: 2006-09-21 14:28
帖子: 2376
送出感谢: 0 次
接收感谢: 0 次
引用:
跳过continue是因为执行
引用:
scanf("%c", &key);


那为什么执行了它,就不行呢?
我要的是根本原因,请您应该从底层上答。

这个问题长期有效,只要我觉得原因比较科学,我会请您留下网银帐号的。


_________________
http://lee.youxu.info/


页首
 用户资料  
 
9 楼 
 文章标题 :
帖子发表于 : 2008-04-30 17:23 

注册: 2007-09-12 16:42
帖子: 2
送出感谢: 0 次
接收感谢: 0 次
输入不满足do{}while()条件

自然在程序执行后输入两个ENTER程序就直接到main的最后了

直接返回了

还有将scanf("%c", &key)改为scanf(" %c", &key)
就是在%前加个空格
因为输入虽然只是一个字符,但其后跟随的回车也输入缓冲中
%前加空格可以忽略非符号字符


页首
 用户资料  
 
10 楼 
 文章标题 :
帖子发表于 : 2008-05-01 23:01 
头像

注册: 2008-02-18 0:25
帖子: 424
送出感谢: 0 次
接收感谢: 0 次
回车也是字符 ASCII: 10


_________________
图片


页首
 用户资料  
 
11 楼 
 文章标题 :
帖子发表于 : 2008-05-30 20:25 
头像

注册: 2006-09-21 14:28
帖子: 2376
送出感谢: 0 次
接收感谢: 0 次
stlxv 解决了一个问题。其他同学的回答对我没有任何帮助。

最近由于时间问题,没有空去研究这个小问题了。

先累积 stlxv 25 RMB :D :D

八月要开始开发 shuge 客户端,用 C 的机会还是有很多的,自然会再有问题请教 stlxv 滴~~ :D :D


_________________
http://lee.youxu.info/


页首
 用户资料  
 
12 楼 
 文章标题 :
帖子发表于 : 2008-06-09 23:39 

注册: 2006-03-01 11:07
帖子: 53
送出感谢: 0 次
接收感谢: 0 次
我自己也没有看过你的代码,但是好像也知道是什么问题了.
上面同学已经解决你的问题了.
看下面的代码
代码:
#include <stdio.h>
int main (int argc, char *argv[])
{
  char ch;
  for (;;)
  {
    scanf ("%c", &ch);
    if (ch == '\n')
      break;
  }
  return 0;
}

运行一下你就会知道结果了.
你只要注意到当你输入时
abcd回车时候
你输入的是,即留在你输入缓冲区的内容为(根据操作系统不一样,可能也会有所不同,如果在mac上进行可能会出现不同的结果)
abcd\n


页首
 用户资料  
 
13 楼 
 文章标题 :
帖子发表于 : 2008-06-09 23:45 
头像

注册: 2006-09-21 14:28
帖子: 2376
送出感谢: 0 次
接收感谢: 0 次
楼上白说 :D :D :D :D


_________________
http://lee.youxu.info/


页首
 用户资料  
 
14 楼 
 文章标题 :
帖子发表于 : 2008-06-10 8:47 
头像

注册: 2008-02-06 13:30
帖子: 172
地址: 浙江嘉兴
送出感谢: 0 次
接收感谢: 0 次
flyinflash 写道:
楼上白说 :D :D :D :D


:D


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 14 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 4 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译