user-0 提问: while循环进入的次数疑惑

回复:
user: user-1
content: 引用 11 楼 wenpinglaoyao 的回复:楼主你的源代码里面，struct student *q 根本就没有初始化。 所以那句【 q->next = pi; 】就是非法地址。。。 我也觉得这个q怪怪的，出现过，只是声明了而已

user: user-2
content: 恩 10楼方法可以的，fflush在不同平台实现方式不同，scanf在VC下微软还搞了个scanf_s，优化了这个比较bug的缓冲区处理。 另外，给个建议啊，代码缩进注意点，一般像初始化这种int a = 1;空一格就好了吧。 PS 昨天木有上班，今天上班才来看下- -

user: user-3
content: 楼主你的源代码里面，struct student *q 根本就没有初始化。 所以那句【 q->next = pi; 】就是非法地址。。。

user: user-4
content: 引用 9 楼 u013990248 的回复:成功了吗？我输入一个字符，比如‘w’回车，程序输出就是a=w b=回车，直接不能输入下一个字符了 windows下是好用的 貌似fflush这个函数实现的不一样  可以自己过滤类似这样void clean_stdin(void) { int c; do { c = getchar(); } while (c != '\n' && c != EOF); }

user: user-4
content: 引用 6 楼 u013990248 的回复:恩，懂了，但是我尝试了使用fflush（stdin）始终清除缓存区的内容，一个最简单的例子： #include <stdio.h> #include <string.h>  int main(void) {         char    a;         char    b       = 'x';         scanf("%c", &a);         fflush(stdin);         b       = getchar();         printf("a=%c, b=%c", a, b);         return 0; }  你这个成功了啊 q回车 w回车 //如果没有flush,a=q, b=回车

user: user-0
content: 成功了吗？我输入一个字符，比如‘w’回车，程序输出就是a=w b=回车，直接不能输入下一个字符了

user: user-0
content: 始终无法清除缓存区的内容

user: user-0
content: 恩，懂了，但是我尝试了使用fflush（stdin）始终清除缓存区的内容，一个最简单的例子： #include <stdio.h> #include <string.h>  int main(void) {         char    a;         char    b       = 'x';         scanf("%c", &a);         fflush(stdin);         b       = getchar();         printf("a=%c, b=%c", a, b);         return 0; }

user: user-2
content: scanf这玩意不是到换行为止的么，你用scanf("%ld%s", &(pi->num), pi->name);读长整形和char*木有问题是因为第二次缓冲区进来的是\n%ld%s啊，然后又有个回车\n在缓冲区里，循环继续你这时去scanf("%c", &ch);，自然这个\n就进来了，然后又非y非n就走下面逻辑了，然后循环继续，缓冲区木有东西，自然等待你输入了。 所以出现两次printf("你要创建结点吗 y/n \n");，所以各大C的书籍里的代码里都会清空缓冲的代码在，无论是while空循环或者fflush(stdin)。

user: user-0
content: 缓存区有东西？能否说得详细点呢？

user: user-0
content: 我也是很久没写了，今天翻书来看看，刚刚发现自己程序上有错误的地方， #include <stdio.h> #include <stdlib.h> #include <string.h>  // 创建单链表、遍历单链表 // 存储学生的信息，包括姓名和学号 struct student {         long      num;         char      name[30];         struct    student *next; };  int main(void) {         //-----------------------创建单链表----------------------------------------------//          struct student   *head; // 头结点         struct student   *tail; // 尾节点         struct student   *pi;   // 可操作的指针变量         struct student   *q;    // 指向当前结点的下一个结点         char   ch;              // 接收键盘的输入         int    first    = 0;    // 判断是否为头结点          // 创建接下来的结点         while(1){                 printf("你要创建结点吗 y/n \n");                 scanf("%c", &ch);                 if(ch=='y'||ch=='Y'){                         pi      = (struct student *)malloc(sizeof(struct student));                         // 判断分配内存是否成功                         if(!pi){                                 printf("分配内存失败，退出程序\n");                                 exit(-1);                         }                          scanf("%ld%s", &(pi->num), pi->name);                         first++;                         pi->next        = NULL;                 }else if(ch=='n'||ch=='N'){                         break; // 跳出循环                 }else{                         continue;                 }                 if(first==1){                         head    = pi;                 }else if(first>1){                         tail->next      = pi; // 建立中间的那条链                 }                 tail    = pi; // 并且将尾指针指向他         }          // -----------------------------------------遍历单链表----------------------------------//         if(first>0){                 pi      = head;                 while(pi){                         printf("%ld     %s\n", pi->num, pi->name);                         pi      = pi->next;                 }         }          // 释放这些内存         if(first>1){                 pi      = head;                 while(pi){                         q       = pi;                         pi      = pi->next;                         free(q);                 }         }else if(first==1){                 free(head);         }          // 当没有创建结点的时候就可以直接返回了          return  0; } 至于为什么会出现两次“要求输入字符的提示”还是没想通。

user: user-2
content: 额 上面手贱发快了... scanf("%ld%s", &(pi->num), pi->name); 因为你在这步执行后缓冲区还是有东西的

user: user-2
content: 好久不写C了..都快不会写了..