| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 749 人关注过本帖
标题:奇怪,怎么会出现缓冲区溢出呢?
取消只看楼主 加入收藏
神龙赖了
Rank: 10Rank: 10Rank: 10
来 自:萨塔星
等 级:青峰侠
威 望:2
帖 子:711
专家分:1788
注 册:2012-10-13
结帖率:97.22%
收藏
已结贴  问题点数:30 回复次数:7 
奇怪,怎么会出现缓冲区溢出呢?
程序代码:
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#include <string.h>
#define SIZE 6
const char black_d='@';  //电脑用的棋子
const char white_p='O';  //玩家用的棋子

void qi_pan(char board[][SIZE]);  //显示棋盘
void shuo_ming(void);  //说明规则
int valid_moves(char board[][SIZE],bool moves[][SIZE],char player);  /*确定有效步骤*/
void make_move(char board[][SIZE],int row,int col,char player);  //完成落子后的“兵变”
void computer_move(char board[][SIZE],bool moves[][SIZE],char player);  //电脑移动
int get_score(char board[][SIZE],char player);  //辅助函数,得到我方棋子数
int best_move(char board[][SIZE],bool moves[][SIZE],char player);  //辅助函数,得到最佳分数

int main(void)
{
    char board [SIZE][SIZE]={0};
    bool moves [SIZE][SIZE]={0};
    char answer[12];
    int row=0;
    int col=0;
    int mid=0;
    int no_of_moves=0;               /*记录棋子number*/
    int no_of_game=0;                /*记录游戏count*/
    int invalid_moves=0;             /*无效次数*/
    int comp_score=0;                /*电脑棋子数*/
    int user_score=0;                /*用户棋子数*/
    bool next_player=true;           /*true为电脑下,flase为user下*/
    int x = 0;                       /*记录user输入的行数*/
    char y = 0;                      /*记录user输入的列数*/

    printf("\n翻转棋戏\n\n");
    printf("你能在这里和电脑对弈\n");
    printf("你将使用白棋,电脑使用黑棋\n");
    printf("如不明白游戏规则请输入help,那里将会对游戏规则进行详细讲解\n");
    printf("否则输入go开始游戏(也可以输入out直接退出):");
    fgets(answer,sizeof(answer),stdin);
    if(tolower(answer[0])=='h')
    shuo_ming();  //检测是否需要解释

    /*start the game*/
    while((tolower(answer[0])=='g' && tolower(answer[1])=='o') || tolower(answer[0])=='h')
    {
        next_player= !next_player;
        no_of_moves=4;  /*记录开盘棋子数*/

        //设棋盘每处为空格
    for(row=0;row<SIZE;row++)
        for(col=0;col<SIZE;col++)
            board[row][col]=' ';

    mid=SIZE/2;  //开始使首先摆放四颗棋子,故居中
    board[mid-1][mid-1]=board[mid][mid]='@';  //放黑棋
    board[mid-1][mid]=board[mid][mid-1]='O';  //放白棋

    /*与玩家对弈*/
    do
    {
        qi_pan(board);

        //如果是用户下...
        if(next_player = !next_player)
        {
            if(valid_moves(board,moves,white_p))  //还有有效步骤
            {
                //循环直到正确输入
                for(;;)
                {
                    printf("请输入你想要下的地方(行 列):");
                    scanf(" %d %c",&x,&y);
                    getchar();
                    y=tolower(y)-'a';  //转换为列索引
                    x--;  //转换为行索引
                    if(x>=0 && x<SIZE && y>=0 && y<SIZE && moves[x][y])
                    {
                        make_move(board,row,col,'O');
                        no_of_moves++;
                        break;
                    }
                    else
                        printf("你输入的为无效棋子,请重新输入\n");
                }
            }

            //当没有有效步骤时...
            else
            if(++invalid_moves<2)
                printf("你以没有有效步骤,所以你必须跳过\n");
            else
                printf("我们都没有可动的地方了,所以棋局结束:");
        }
        else
        {
            //电脑'true
            if(valid_moves(board,moves,'@'))
            {
                computer_move(board,moves,'@');
                no_of_moves++;
                break;
            }
            else
            if(++invalid_moves<2)
                printf("我没有可动的地方,所以我必须跳过,请你继续输入");
            else
                printf("我们都没有可动的地方了,所以棋局结束:");
        }
    }while(no_of_moves<SIZE*SIZE && invalid_moves<2); 

        /*处理结果*/
        qi_pan(board);  //显示最后结果的棋盘
        comp_score=user_score=0;  

        //浏览全盘
        for(row=0;row<SIZE;row++)
            for(col=0;col<SIZE;col++)
            {
                user_score += board[row][col] == white_p;
                comp_score += board[row][col] == black_d;
            }

            printf("\n结果为:\n");
            printf("白棋%2d  \n黑棋%2d\n\n",user_score,comp_score);
            printf("你还想继续下去吗?(go/out):");
            fgets(answer,sizeof(answer),stdin);
            printf("%s\n",answer);
    }
    return 0;
}

因为程序有点大,所以只把main函数放出来了,
考虑到程序有点大,如果嫌麻烦的话不用太看上面的代码
我想问的是:
程序代码:
int main(void)
{
    char a,b,c;
    scanf("%c",&a);
    printf("a==%c\n",a);
    scanf(" %c",&b);
    printf("b==%c\n",b);
    scanf("%c",&c);
    printf("%c\n",c);
    return 0;
}

中scanf()会遗留下‘\n',而( %d)只能跳过却不能删除
可是:
程序代码:
#include <stdio.h>

int main(void)
{
    char a,b,c;
    scanf("%c",&a);
    printf("a==%c\n",a);
    scanf(" %c",&b);
    printf("b==%c\n",b);
    return 0;
}
虽然在缓冲区遗留了一个'\n'却也不是溢出
那缓冲区溢出到底是什么意思啊?

希望能讲清楚点,谢谢

 
搜索更多相关主题的帖子: 缓冲区 
2012-11-18 10:29
神龙赖了
Rank: 10Rank: 10Rank: 10
来 自:萨塔星
等 级:青峰侠
威 望:2
帖 子:711
专家分:1788
注 册:2012-10-13
收藏
得分:0 
我知道getchar()和fflush(stdin)可以清空缓冲区,但用在这里不对
问题主要出在那几个函数中,现在我已经改过来了,好吧,楼上打酱油的,还是谢谢你了...

我有个关于scanf()的问题
  
程序代码:
#include <stdio.h>

int main(void)
{
    char a=0,b=0;
    scanf("%c",&a);
    printf("a==%d\n",a);
    scanf("%c",&b);
    printf("b==%d\n",b);
    return 0;
}

连续输入两个回车会得到'\n'的ASCLL值10;
而如果在scanf("%c",&b);的后面加上getchar()
的话在遇到关于b的输入的时候需要连续打两下空格
也许这也关系到缓冲区,但是我实在弄不懂其中的运行
希望能一步一步详细写出内部运行,当然如果能使我弄懂自然照样给分啦,非常感谢!

I have not failed completely
2012-11-18 20:58
神龙赖了
Rank: 10Rank: 10Rank: 10
来 自:萨塔星
等 级:青峰侠
威 望:2
帖 子:711
专家分:1788
注 册:2012-10-13
收藏
得分:0 
后面加上getchar()
的话在遇到关于b的输入的时候需要连续打两下空格

是连续打两下回车,笔误笔误...

I have not failed completely
2012-11-18 21:00
神龙赖了
Rank: 10Rank: 10Rank: 10
来 自:萨塔星
等 级:青峰侠
威 望:2
帖 子:711
专家分:1788
注 册:2012-10-13
收藏
得分:0 
回复 6楼 youngdavid
我基本懂了,但是getchar()如果那么用的话就是查看缓冲区内的信息,getchar()又可以用来清除,搞得我有点混乱...能不能讲一下这一步
while(getchar()!='\n')
    continue;

分还是先结了吧,免得人家说我不厚道...

I have not failed completely
2012-11-18 21:55
神龙赖了
Rank: 10Rank: 10Rank: 10
来 自:萨塔星
等 级:青峰侠
威 望:2
帖 子:711
专家分:1788
注 册:2012-10-13
收藏
得分:0 
哎,真是云里雾里 雾里云里,似懂非懂啊...还是先不想了吧..。

I have not failed completely
2012-11-18 22:18
神龙赖了
Rank: 10Rank: 10Rank: 10
来 自:萨塔星
等 级:青峰侠
威 望:2
帖 子:711
专家分:1788
注 册:2012-10-13
收藏
得分:0 
哟西,我恍然大悟了,你滴,良民滴干活!

I have not failed completely
2012-11-19 19:15
神龙赖了
Rank: 10Rank: 10Rank: 10
来 自:萨塔星
等 级:青峰侠
威 望:2
帖 子:711
专家分:1788
注 册:2012-10-13
收藏
得分:0 
好吧,其实我已经看过了...写得不错,多想一下也看懂了
比如我们在键盘上敲下了123456这个字符串,然后敲一下回车键(\r)将这个字符串送入了缓冲区中,那么此时缓冲区中的字节个数是7 ,而不是6。
这里我想问一下,因为"123456"是一个字符串,那终止符'\0'应该也会被带入缓冲区吧
如果是我错了的话就帮忙讲下具体的内部运行,Thanks.

I have not failed completely
2012-11-19 20:30
神龙赖了
Rank: 10Rank: 10Rank: 10
来 自:萨塔星
等 级:青峰侠
威 望:2
帖 子:711
专家分:1788
注 册:2012-10-13
收藏
得分:0 
...好吧...

I have not failed completely
2012-11-19 21:15
快速回复:奇怪,怎么会出现缓冲区溢出呢?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.032591 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved