关于gets()函数一个很纠结的问题,具体请进

TrustTJM 2012-11-05 10:12:24
代码很长(是操作系统关于模拟先来先服务算法的),所以我事先说一下问题的所在看一下图片

等下请各位大神看下gets()函数,第一次循环能用,第二次就不行了。。。代码中就有一个...这个问题是在让我无语了很久,DEBUG也没有找出头绪


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

struct fcfs_member
{
char Process_name[10]; //进程名
int Arrival_time; //到达时间
int Service_time; //服务时间
int Start_time; //开始执行时间
int Completion_time; //完成时间
int Turnaround_time; //周转时间
float Weighted_turnover_time; //带权周转时间
};

void main()
{
int system(const char *string); //声明清屏函数

struct fcfs_member FCFS_member[4];

printf("下面为一个实例,如果仅测试程序,可按下面数据进行输入\n");
printf("进程名 到达时间 服务时间 开始执行时间 完成时间\n");
printf(" A 0 1 0 1\n");
printf(" B 1 100 1 1\n");
printf(" C 2 1 101 102\n");
printf(" D 3 100 102 202\n\n");

printf("请输入四组数据!连续输入对应数据以空格分隔\n\n");

//------------------------导入数据,并进行排序-----------------------------
int i, j;
for(i=0; i<4; i++)
{
printf("第%d组\n", i+1);

printf("进程名:");
gets(FCFS_member[i].Process_name);

printf("\n到达时间 服务时间 开始执行时间 完成时间\n");
scanf("%d %d %d %d", &FCFS_member[i].Arrival_time,
&FCFS_member[i].Service_time,
&FCFS_member[i].Start_time,
&FCFS_member[i].Completion_time);

//计算周转时间和带权周转时间
FCFS_member[i].Turnaround_time = FCFS_member[i].Completion_time - FCFS_member[i].Arrival_time;
FCFS_member[i].Weighted_turnover_time = (float)FCFS_member[i].Turnaround_time / (float)FCFS_member[i].Service_time;
}

int flag = 1; //标记排序,避免多次循环判断,提高效率
for(i=0; i<3 && flag == 1; i++)
{
flag = 0;
for(j=0; j<4-i; j++)
{
if(FCFS_member[j].Arrival_time > FCFS_member[j+1].Arrival_time)
{
char temp_string[10];

//交换进程名
strcpy(temp_string, FCFS_member[j].Process_name);
strcpy(FCFS_member[j].Process_name,
FCFS_member[j+1].Process_name);
strcpy(FCFS_member[j+1].Process_name, temp_string);

//交换到达时间
FCFS_member[j].Arrival_time = FCFS_member[j].Arrival_time ^ FCFS_member[j+1].Arrival_time;
FCFS_member[j+1].Arrival_time = FCFS_member[j+1].Arrival_time ^ FCFS_member[j].Arrival_time;
FCFS_member[j].Arrival_time = FCFS_member[j].Arrival_time ^ FCFS_member[j+1].Arrival_time;

//交换服务时间
FCFS_member[j].Service_time = FCFS_member[j].Service_time ^ FCFS_member[j+1].Service_time;
FCFS_member[j+1].Service_time = FCFS_member[j+1].Service_time ^ FCFS_member[j].Service_time;
FCFS_member[j].Service_time = FCFS_member[j].Service_time ^ FCFS_member[j+1].Service_time;

//交换开始执行时间
FCFS_member[j].Start_time = FCFS_member[j].Start_time ^ FCFS_member[j+1].Start_time;
FCFS_member[j+1].Start_time = FCFS_member[j+1].Start_time ^ FCFS_member[j].Start_time;
FCFS_member[j].Start_time = FCFS_member[j].Start_time ^ FCFS_member[j+1].Start_time;

//交换完成时间
FCFS_member[j].Completion_time = FCFS_member[j].Completion_time ^ FCFS_member[j+1].Completion_time;
FCFS_member[j+1].Completion_time = FCFS_member[j+1].Completion_time ^ FCFS_member[j].Completion_time;
FCFS_member[j].Completion_time = FCFS_member[j].Completion_time ^ FCFS_member[j+1].Completion_time;

//交换周转时间
FCFS_member[j].Turnaround_time = FCFS_member[j].Turnaround_time ^ FCFS_member[j+1].Turnaround_time;
FCFS_member[j+1].Turnaround_time = FCFS_member[j+1].Turnaround_time ^ FCFS_member[j].Turnaround_time;
FCFS_member[j].Turnaround_time = FCFS_member[j].Turnaround_time ^ FCFS_member[j+1].Turnaround_time;

//交换带权周转时间
float temp;
temp = FCFS_member[j].Weighted_turnover_time;
FCFS_member[j].Weighted_turnover_time = FCFS_member[j+1].Weighted_turnover_time;
FCFS_member[j+1].Weighted_turnover_time = temp;
}
}
}
//----------------执行阶段---------------------------------
printf("进程名 到达时间 服务时间 开始执行时间 完成时间 周转时间 带权周转时间\n");
for(i=0; i<4; i++)
{
for(j=0; j<FCFS_member[i].Service_time; j++)
{
printf("%10s %5d %5d", FCFS_member[i].Process_name,
FCFS_member[i].Arrival_time,
j);
Sleep(500); //延迟计数时间

printf("%5d %5d %5d %5.3f\n", FCFS_member[i].Start_time,
FCFS_member[i].Completion_time,
FCFS_member[i].Turnaround_time,
FCFS_member[i].Weighted_turnover_time);
Sleep(500); //延迟计数时间
system("cls"); //清屏
}
}


}
...全文
691 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
易猜 2013-09-09
  • 打赏
  • 举报
回复
终于解决了我的问题,真的很感谢你们!太感谢了!问了好多同学没有解决!
TrustTJM 2012-11-10
  • 打赏
  • 举报
回复
引用 18 楼 proorck6 的回复:
这样做,把代码放在框里,就好看多了。
谢谢!!!!学习到了
proorck6 2012-11-09
  • 打赏
  • 举报
回复

这样做,把代码放在框里,就好看多了。
14号选手 2012-11-09
  • 打赏
  • 举报
回复
引用 16 楼 Dennkyuu 的回复:
引用 7 楼 xuchao1229 的回复:正如四楼所言 数组的长度是要设置好的,用gets()函数是有一个缺点的,你输入多少它就接受多少,这样就很容易占用后面的空间,著名的“蠕虫病毒就是因为这个函数导致的” 所以,输入字符串尽量在数组长度之内,也不要忘了给最后的结束标志留一个位置,不然的话,换行符是会留在缓冲区,占据其他数据的位置的 问下,“给最后的结束标……
就是字符串最后的结束标志'\0',标志着字符串到这里就没有了啊 上次我在写一个结构体的时候就忽略了这一点,结果导致输出的结构不正确
電球 2012-11-09
  • 打赏
  • 举报
回复
引用 7 楼 xuchao1229 的回复:
正如四楼所言 数组的长度是要设置好的,用gets()函数是有一个缺点的,你输入多少它就接受多少,这样就很容易占用后面的空间,著名的“蠕虫病毒就是因为这个函数导致的” 所以,输入字符串尽量在数组长度之内,也不要忘了给最后的结束标志留一个位置,不然的话,换行符是会留在缓冲区,占据其他数据的位置的
问下,“给最后的结束标志留一个位置” 具体是怎么表现的、 “换行符留在缓冲区” 不大明白。
電球 2012-11-09
  • 打赏
  • 举报
回复
这是我们最近刚学的操作系统咩。 FCFS跟SJF。。。
TrustTJM 2012-11-09
  • 打赏
  • 举报
回复
谢谢各位的帮忙,我会认真的给分的
TrustTJM 2012-11-09
  • 打赏
  • 举报
回复
引用 11 楼 zhao4zhong1 的回复:
应改为 C/C++ code12fgets(FCFS_member[i].Process_name,10,stdin);if ('\n'==FCFS_member[i].Process_name[strlen(FCFS_member[i].Process_name)-1]) FCFS_member[i].Process_name[strlen(FCFS_member[i……
这位大神好牛!我会仔细研究这个语句的!
TrustTJM 2012-11-09
  • 打赏
  • 举报
回复
引用 10 楼 yinlincheng 的回复:
我也跑了一下,然后将gets()改为scanf("%s",FCFS_member[i].Process_name)就没问题了,这里主要是缓冲区的问题,gets接受了上一次输出的回车符,默认接受了符号,所以程序会自动跳过;
额,是scanf("%s",&FCFS_member[i].Process_name)吧,本来是想读取一行字符,慢慢处理的,不过还是算了,然后不想重复用scanf太多,不过 还是学习到了
赵4老师 2012-11-09
  • 打赏
  • 举报
回复
应改为
fgets(FCFS_member[i].Process_name,10,stdin);
if ('\n'==FCFS_member[i].Process_name[strlen(FCFS_member[i].Process_name)-1]) FCFS_member[i].Process_name[strlen(FCFS_member[i].Process_name)-1]=0;
yinlincheng 2012-11-09
  • 打赏
  • 举报
回复
我也跑了一下,然后将gets()改为scanf("%s",FCFS_member[i].Process_name)就没问题了,这里主要是缓冲区的问题,gets接受了上一次输出的回车符,默认接受了符号,所以程序会自动跳过;
gaochizhen33 2012-11-09
  • 打赏
  • 举报
回复
引用 3 楼 luckytjm 的回复:
引用 2 楼 JiMoKuangXiangQu 的回复:C/C++ code1234567891011#include <stdio.h> void main(){ char buf[1024]; while (gets(buf)) printf("%s\n", buf); return 0;} 输入: abc 输出: ab……
这个应该是典型的换行符号被存储在缓存里的问题了吧。 你每次循环结束之前,调用一下getchar()函数,把回车清除掉应该就好了。
wayne_hust 2012-11-09
  • 打赏
  • 举报
回复
利用scanf函数从键盘接收一字符(或整数)时,它只读入字符(或整数)本身,而把字符(或整数)后的回车符留在输入缓冲区内;gets函数从标准的输入读取,如果使用gets函数给字符数组输入字符串时,字符数组不能指定长度,因为,只要字符数组的长度小于gets函数读取的行缓存的大小,即使你输入的字符数大于你所规定的字符数组的长度,gets函数也会接收所输入的全部字符,造成字符数组越界。因此,gets是一个不推荐使用的函数。一般对于初学者来说,容易把scanf和gets函数混用,出现一些问题,有下面两种情况: 1、gets在scanf前调用,这种调用一般不会出现什么问题,可以正常输入。 2、scanf在gets前调用,这种情况就会出现问题,当输入完scanf中的变量时,运行到gets函数,则不让输入任何字符,出现此问题的原因是gets函数接收了scanf输入完后的回车符,解决的办法是在scanf和gets中间,用getchar函数接收掉回车符,这样就不会出现任何问题了。但是这个只能解决有一个换行符的问题。 要想解决多个的问题,可以在scanf之后使用下面的代码来做

if(getchar()!='\n')
{
   continue;
}
不过说真的建议别使用gets,不是很安全,而且只适用于玩具程序。
14号选手 2012-11-07
  • 打赏
  • 举报
回复
正如四楼所言 数组的长度是要设置好的,用gets()函数是有一个缺点的,你输入多少它就接受多少,这样就很容易占用后面的空间,著名的“蠕虫病毒就是因为这个函数导致的” 所以,输入字符串尽量在数组长度之内,也不要忘了给最后的结束标志留一个位置,不然的话,换行符是会留在缓冲区,占据其他数据的位置的
Evil_Logic 2012-11-07
  • 打赏
  • 举报
回复
引用 4 楼 jiemo1123 的回复:
输入缓存没有清空,在用标准输入时,换行是会存在缓冲区的,比如 C/C++ code12345678int nA = 0;while(1){ printf("请输入一个数组"); scanf("%d",&nA); printf("输入的数字是%d", nA);} 第一次会停止在scanf,第二次就不会,因为第一次缓冲区没有东西,第二次有一个换……
正解
TrustTJM 2012-11-07
  • 打赏
  • 举报
回复
引用 4 楼 jiemo1123 的回复:
输入缓存没有清空,在用标准输入时,换行是会存在缓冲区的,比如 C/C++ code12345678int nA = 0;while(1){ printf("请输入一个数组"); scanf("%d",&nA); printf("输入的数字是%d", nA);} 第一次会停止在scanf,第二次就不会,因为第一次缓冲区没有东西,第二次有一个换……
这位仁兄很有理,我去试试!行了就给分
jiemo1123 2012-11-05
  • 打赏
  • 举报
回复
输入缓存没有清空,在用标准输入时,换行是会存在缓冲区的,比如

int nA = 0;
while(1)
{
    printf("请输入一个数组"); 
    scanf("%d",&nA);
    printf("输入的数字是%d", nA);
}
第一次会停止在scanf,第二次就不会,因为第一次缓冲区没有东西,第二次有一个换行符,所以不会停止,windows下可以在每个scanf后面加上fflush(stdin)来清除缓冲区的内容
TrustTJM 2012-11-05
  • 打赏
  • 举报
回复
引用 2 楼 JiMoKuangXiangQu 的回复:
C/C++ code1234567891011#include <stdio.h> void main(){ char buf[1024]; while (gets(buf)) printf("%s\n", buf); return 0;} 输入: abc 输出: abc 输入: hij 输出: hij 输……
这位仁兄。。。能不能把我的程序复制粘贴运行一下行么,这个程序语法没有错误,可以运行的,就是第一次循环行,第二次却不行了
JiMoKuangXiangQu 2012-11-05
  • 打赏
  • 举报
回复
#include <stdio.h>

void main()
{
	char buf[1024];

	while (gets(buf))
		printf("%s\n", buf);

	return 0;
}
输入: abc 输出: abc 输入: hij 输出: hij 输入: CTRL+Z 结束 单独把gets()逻辑拿出来,看看自己的gets()代码逻辑有没有问题,如果没有.应该就是其他问题.
TrustTJM 2012-11-05
  • 打赏
  • 举报
回复
不好意思,tab键的空格显示不出来,可能看代码的时候给各位带来一些困难,我忘了是直接从VC复制过来的

70,029

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧