悬赏 50 人民币求 C 语言基础习题解

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

悬赏 50 人民币求 C 语言基础习题解

#1

帖子 flyinflash » 2008-04-25 18:54

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;
  
}
头像
hcym
帖子: 15634
注册时间: 2007-05-06 2:46

#2

帖子 hcym » 2008-04-25 19:07

50 人民币

:em14

楼主没见过人民币

:em23
头像
stlxv
论坛版主
帖子: 8275
注册时间: 2006-05-03 0:39
来自: المريخ

#3

帖子 stlxv » 2008-04-25 19:31

代码: 全选

// 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是最好的语言!不服来战!
头像
tipfoo
帖子: 303
注册时间: 2007-07-12 16:30
来自: 桂林

Re: 悬赏 50 人民币求 C 语言基础习题解

#4

帖子 tipfoo » 2008-04-26 8:13

flyinflash 写了: 确保上面源代码能通过 TC 2.0~3.0、 MVC++ 6.0、GCC 3.4~4.1 编译,并且无错、无警告
不是谁都愿意为了几个编译工具去装这么多东东,要求GCC就够了。 :em14
flyinflash
帖子: 2376
注册时间: 2006-09-21 14:28

#5

帖子 flyinflash » 2008-04-26 15:47

我要保留 continue 呢?

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



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

嗯,正想请教一下 RMS
头像
异域追梦者
帖子: 424
注册时间: 2008-02-18 0:25
联系:

#6

帖子 异域追梦者 » 2008-04-26 19:50

跳过continue是因为执行

代码: 全选

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

代码: 全选

scanf("%c", &key);
getchar();
按Enter退出是因为不满足do~while的循环条件, 可以改成

代码: 全选

do
{
  ...
}
while ((key != 'q') && (key != 'Q'));
我这里没有TC和VC, 抱歉不能测试, GCC通过.
图片
头像
yangcheng
帖子: 498
注册时间: 2005-09-27 18:24
来自: 杭州

Re: 悬赏 50 人民币求 C 语言基础习题解

#7

帖子 yangcheng » 2008-04-27 9:28

flyinflash 写了:1、
修正以下漏洞:
1、逃过 continue
2、主菜单按 enter 导致退出程序

确保上面源代码能通过 TC 2.0~3.0、 MVC++ 6.0、GCC 3.4~4.1 编译,并且无错、无警告
tc这个太令人发指了,谁还有阿。
vc 6不免费,没装 不过还是学生,vs2008倒是可以免费用 呵呵
flyinflash
帖子: 2376
注册时间: 2006-09-21 14:28

#8

帖子 flyinflash » 2008-04-28 17:52

跳过continue是因为执行
scanf("%c", &key);
那为什么执行了它,就不行呢?
我要的是根本原因,请您应该从底层上答。

这个问题长期有效,只要我觉得原因比较科学,我会请您留下网银帐号的。
A4B5
帖子: 2
注册时间: 2007-09-12 16:42

#9

帖子 A4B5 » 2008-04-30 17:23

输入不满足do{}while()条件

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

直接返回了

还有将scanf("%c", &key)改为scanf(" %c", &key)
就是在%前加个空格
因为输入虽然只是一个字符,但其后跟随的回车也输入缓冲中
%前加空格可以忽略非符号字符
头像
异域追梦者
帖子: 424
注册时间: 2008-02-18 0:25
联系:

#10

帖子 异域追梦者 » 2008-05-01 23:01

回车也是字符 ASCII: 10
图片
flyinflash
帖子: 2376
注册时间: 2006-09-21 14:28

#11

帖子 flyinflash » 2008-05-30 20:25

stlxv 解决了一个问题。其他同学的回答对我没有任何帮助。

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

先累积 stlxv 25 RMB :D :D

八月要开始开发 shuge 客户端,用 C 的机会还是有很多的,自然会再有问题请教 stlxv 滴~~ :D :D
liway
帖子: 53
注册时间: 2006-03-01 11:07

#12

帖子 liway » 2008-06-09 23:39

我自己也没有看过你的代码,但是好像也知道是什么问题了.
上面同学已经解决你的问题了.
看下面的代码

代码: 全选

#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
flyinflash
帖子: 2376
注册时间: 2006-09-21 14:28

#13

帖子 flyinflash » 2008-06-09 23:45

楼上白说 :D :D :D :D
头像
alan110_38
帖子: 172
注册时间: 2008-02-06 13:30
来自: 浙江嘉兴

#14

帖子 alan110_38 » 2008-06-10 8:47

flyinflash 写了:楼上白说 :D :D :D :D
:D
回复