wueuwu 发表于 2020-6-4 18:21:23

清空缓冲区的问题

本帖最后由 wueuwu 于 2020-6-4 19:43 编辑

int Push(SqStack &S, char e) {
      
      //printf("输入字符:");
      if(scanf("%c", &e) != EOF){
      while ((e = getchar()) != '\n' && e != EOF);}
      //e = getchar();
      if (S.top - S.base >= S.stacksize) {
                S.base = (char*)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(char));
                if (!S.base) exit(1);
                S.top = S.base + S.stacksize;
                S.stacksize += STACKINCREMENT;
      }
      *S.top++ = e;
      return OK;
}


、、、、、、、、、、、、、、、、

wueuwu 发表于 2020-6-4 18:22:44

本帖最后由 wueuwu 于 2020-6-4 18:34 编辑

好像图片没显示出来。
我是想从控制台输入字符,而不是一个静态的值
vs2017上
if (S.top - S.base >= S.stacksize) {
                S.base = (char*)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(char));报错
要清空缓冲区,但是看到的解决办法

while ((e = getchar()) != '\n' && e != EOF);不起作用。
fflush更不用说。
rewind也不行。请问各位,有什么办法在vs中可以清空缓冲区。还是说我的方向本身就是错的
0x782FAACD (ucrtbased.dll)处(位于 Project41.exe 中)引发的异常: 0xC0000005: 读取位置 0xCCCCCCC4 时发生访问冲突。

我叫MD 发表于 2020-6-4 18:33:44

没读懂程序想要做什么,可否把你的工程打包发下

永恒的蓝色梦想 发表于 2020-6-4 18:39:56

wueuwu 发表于 2020-6-4 18:22
好像图片没显示出来。
我是想从控制台输入字符,而不是一个静态的值
vs2017上


???

wueuwu 发表于 2020-6-4 19:08:19

我叫MD 发表于 2020-6-4 18:33
没读懂程序想要做什么,可否把你的工程打包发下

之前没打包过,花时间弄了一下。现在好像不知道怎么发出来。。

CodingCat_k 发表于 2020-6-4 19:35:08

主要是结构体不知道你的是什么
单看代码:S.top - S.base >= S.stacksize//这个语句看来你的S.base和S.top是数值
但是后面的操作又像是指针;如果是指针那两个指针做差的意义是指向单元的相差个数而非相差大小;
清空缓冲区:fflush(stdin);或者上面的while(...){...}
还有,报错是访问冲突,一般和缓冲区没啥关系吧,一般就是指针之类错误

wueuwu 发表于 2020-6-4 19:42:11

CodingCat_k 发表于 2020-6-4 19:35
主要是结构体不知道你的是什么
单看代码:S.top - S.base >= S.stacksize//这个语句看来你的S.base和S.top ...

确实有可能是其他问题。只是因为我问了教我的老师,她让我清空缓冲区。结果忙了半天没弄出来。

wueuwu 发表于 2020-6-4 19:44:30

我叫MD 发表于 2020-6-4 18:33
没读懂程序想要做什么,可否把你的工程打包发下

大佬,刚弄到权限,上传了附件。如果可以的,麻烦你一下。

我叫MD 发表于 2020-6-4 20:21:29

本帖最后由 我叫MD 于 2020-6-4 20:39 编辑

wueuwu 发表于 2020-6-4 19:44
大佬,刚弄到权限,上传了附件。如果可以的,麻烦你一下。


你结构体没给初值,就直接使用了,所以报错,本来想给你个修改的建议的,但是不知道你要做什么,所以暂时就不给建议了,问题下面图片说的很清楚了
如果不知道怎么改,告诉我你的流程,可以帮你改下



CodingCat_k 发表于 2020-6-4 20:56:36

问题一:按照楼主给的代码附件,出现访问冲突原因在于冗余的一个SqStack S;
(注意:这个是个局部变量,里面的啥都没有,所以操作他的内存指针产生了访问冲突,因该是代码逻辑混乱,明明main里面有了一个,直接引用就行了;建议修改)
问题二:修改完上述,输入字符仍然不能实现,因为缓冲区卡了换行符,建议在读字符前加getchar();吃了多余的符号,或者网上查找的while(...){..}形式的;fflush(stdin)不知道是平台原因还是其它,效果不理想。
目测功能还未完成,楼主加油

wueuwu 发表于 2020-6-4 20:56:53

我叫MD 发表于 2020-6-4 20:21
你结构体没给初值,就直接使用了,所以报错,本来想给你个修改的建议的,但是不知道你要做什么,所以 ...

是打算从控制台输入字符入栈。
case 1:调用Push函数,控制台交互出现输入字符。要给Push附初值的话,好比:Push('a')之类的不是我想要的。想从控制台输入字符给e赋值,可行吗?
至于if(S.top->S.top>=S.stacksize)S.top->S.top>=S.stacksize)这个我是真不会附初值

wueuwu 发表于 2020-6-4 21:14:37

CodingCat_k 发表于 2020-6-4 20:56
问题一:按照楼主给的代码附件,出现访问冲突原因在于冗余的一个SqStack S;
(注意:这个是个局部变量,里 ...

main里面有SqStack S;我是因为要进行一次初始化,所以在后来的修改过程中加进去的。没想到会这样。
读字符前加getchar()。尝试过了,并没有成功。你往下拉就会发现我尝试过的一些方法。

CodingCat_k 发表于 2020-6-4 21:19:03

wueuwu 发表于 2020-6-4 20:56
是打算从控制台输入字符入栈。
case 1:调用Push函数,控制台交互出现输入字符。要给Push附初值的话,好 ...

可以从控制台给它赋值的;你的push里面的if应该是要实现栈满后补充功能的吧,逻辑上不能给它再初始化了;不然前面的数据全洗掉了

wueuwu 发表于 2020-6-4 21:24:02

CodingCat_k 发表于 2020-6-4 21:19
可以从控制台给它赋值的;你的push里面的if应该是要实现栈满后补充功能的吧,逻辑上不能给它再初始化了; ...

是这么想,问题是他给我出错。。。。

CodingCat_k 发表于 2020-6-4 21:25:35

wueuwu 发表于 2020-6-4 21:14
main里面有SqStack S;我是因为要进行一次初始化,所以在后来的修改过程中加进去的。没想到会这样。
读字 ...

要么就直接以main里面的S为主,把所有需要的数据结构雏形都丢在main里;初始化,以及后续赋值直接引用操作就行了;
读单个字符用下面的语句看看,把函数的定义都统一成对S的引用,子函数内部不出现局部的S可避免内存访问冲突
getchar();//吃多余换行符
e = getchar();//获取输入字符。

我叫MD 发表于 2020-6-4 21:32:57

wueuwu 发表于 2020-6-4 20:56
是打算从控制台输入字符入栈。
case 1:调用Push函数,控制台交互出现输入字符。要给Push附初值的话,好 ...

没懂你说的什么意思
你整个 Push 函数是想做什么事情

wueuwu 发表于 2020-6-4 21:39:31

CodingCat_k 发表于 2020-6-4 21:25
要么就直接以main里面的S为主,把所有需要的数据结构雏形都丢在main里;初始化,以及后续赋值直接引用操 ...

getchar();
e=getchar();也不行。至于把数据结构雏形都丢main里,该怎么理解。把结构体扔里面?

wueuwu 发表于 2020-6-4 21:48:11

我叫MD 发表于 2020-6-4 21:32
没懂你说的什么意思
你整个 Push 函数是想做什么事情

运行的时候,选择到“栈的基本操作”,再选到“进栈”。调用Push函数。
Push函数再运行,比如这时执行printf(“输入数据:”);使用者再从控制台输入数据进栈。(控制台,运行程序之后弹出的窗口)

我叫MD 发表于 2020-6-4 21:50:10

本帖最后由 我叫MD 于 2020-6-4 22:10 编辑

wueuwu 发表于 2020-6-4 21:48
运行的时候,选择到“栈的基本操作”,再选到“进栈”。调用Push函数。
Push函数再运行,比如这时执行pr ...

我给你改下代码5分钟稍等

我给你改了下代码,能用了,Push函数我相当于在你的逻辑上面重写了一下,所以重点是Push函数,我加了很多注释,你应该能看懂

首先,给你的栈初始化
void Stack() {
        int n;
        SqStack S;

        //这里其实就加了这么一行
        memset(&S, 0, sizeof(SqStack));

        do {
                printf("\n");
                printf("****************栈的基本操作及应用*****************\n");
                printf("* 1进栈                                       *\n");
                printf("* 2出栈                                       *\n");
                printf("* 3取栈顶元素                                 *\n");
                printf("* 4应用                                       *\n");
                printf("* 5退出                                       *\n");
                printf("***************************************************\n");
                printf("请选择:");
                scanf_s("%d", &n);
                switch (n) {
                case 1:
                        Push(S); break;
                case 2:
                        Pop(S); break;
                case 3:
                        GetTop(S); break;
                case 4:
                        printf("--------应用-------"); break;
                case 5:break;
                default:
                        printf("ERROR!"); break;
                }
        } while (n != 5);
}


Push函数,这个是你主要看的
int Push(SqStack &S)
{
        //变量赋初值
        char e = '\0';

        //获取输入的字符,如果为换行,则重新获取
        while ((e = getchar()) == '\n')
        {

        }

        //如果还没有申请空间,则申请空间
        if (S.base == NULL || S.top == NULL)
        {
                //先申请 STACKINCREMENT 空间
                S.base = (char*)calloc(sizeof(char), STACKINCREMENT);
                if (S.base == NULL)
                {
                  printf("空间申请失败\n");
                  exit(1);
                }

                //栈顶和栈底指向同一个位置
                S.top = S.base;

                //保存目前栈的大小
                S.stacksize = STACKINCREMENT;
        }
        else
        {
                //如果栈满,则申请更大的空间,将原先的数据保存
                if (S.top - S.base >= S.stacksize)
                {
                        //将栈底指向新申请的空间
                        S.base = (char*)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(char));

                        //恢复栈顶
                        S.top = S.base + S.stacksize;

                        //更新栈的大小
                        S.stacksize += STACKINCREMENT;
                }
        }

        *S.top = e;
        S.top++;

        return OK;
}

Pop函数,给你加了个判断,要不然当你栈空的时候,再弹数据,会出问题
int Pop(SqStack &S)
{
        //这里加了个判断,以后这种小问题的注意
        if (S.top == S.base)
        {
                printf("栈中没有数据\r\n");
                return OK;
        }
        char e;
        e = *--S.top;
        printf("出栈:%c", e);


        return OK;
}



好了,以上就是我修改的地方,你根据函数名,找到对应位置,改一下,应该差不多了
页: [1]
查看完整版本: 清空缓冲区的问题