【发布时间】:2018-04-25 09:46:56
【问题描述】:
我设置了一个挑战来创建一个简单的犯罪报告系统。我最初使用 scanf 来输入数据,但在 fgets 上传输了一些数据,这导致 printf 的多个部分在不要求输入的情况下聚集在一起。此外,代码末尾的报告部分会打印随机符号,我不知道如何删除它们。
#include <stdio.h>
int main ()
{
int incident_day, incident_month, incident_year, incident_hour, incident_minute, dd, mm, yy;
long long int contact_number, wit_contact_number[12];
char safe_place, CRS_qu, medical_qu, incident_address, incident_address_house_no[10], incident_address_street[10], incident_address_postcode[10], assailant_qu;
char assailant_name[20], assailant_address[40], wit_qu, wit_name[20], weapon_description[50], armed_qu[3];
char first_name[20], surname[20];
start:
printf(" Are you in a safe place? (Y/N)\n");
scanf(" %[^\n]s", &safe_place);
while (safe_place == 'N' || safe_place == 'n')
{
printf(" Please contact the police Service immediatly on 999\n");
break;
}
printf(" This Crime Reporting System is for victims on assuault only, Are you a victim on assault? (Y/N)\n");
scanf(" %[^\n]s", &CRS_qu);
while (CRS_qu == 'N' || CRS_qu == 'n')
{
printf(" Please select the appropriate Crime Reporting System related to the crime you want to report\n");
goto start;
}
printf(" Have you had any medical treatment for any injurys sustained during the incident? (Y/N)\n");
scanf(" %[^\n]s", &medical_qu);
while (medical_qu == 'N' || medical_qu == 'n')
{
printf(" Please contact the Ambulance Service on 999 and get imediate medical attention\n");
break;
}
printf(" Please enter the date of the incident? (DD/MM/YY)\n");
scanf("%d/%d/%d", &incident_day, &incident_month, &incident_year);
start2:
printf(" Please enter an approximate time of the incident? Format 24:00\n");
scanf("%d:%d", &incident_hour, &incident_minute);
if (incident_hour <00 || incident_hour >23 || incident_minute <00 || incident_minute >59)
{
printf(" Please enter a valid time in a 24:00 format\n");
goto start2;
}
printf(" Do you know the address of the incident? (Y/N)\n");
scanf(" %[^\n]s", &incident_address);
while ( incident_address == 'Y'|| incident_address == 'y')
{
printf(" Please enter the House No.?\n");
fgets(incident_address_house_no, 10, stdin);
printf(" Please enter the Street Name?\n");
fgets(incident_address_street, 10, stdin);
printf(" Please enter the Postcode?\n");
fgets(incident_address_postcode, 10, stdin);
break;
}
printf(" Do you know the assailant? (Y/N)\n");
scanf(" %[^\n]s", &assailant_qu);
while ( assailant_qu == 'Y' || assailant_qu == 'y')
{
printf(" Enter the assailants name?\n");
fgets(assailant_name, 20, stdin);
printf(" Enter the assailants address?\n");
fgets(assailant_address, 40, stdin);
break;
}
while ( assailant_qu == 'N' || assailant_qu == 'n')
{
printf(" A detective will be incontact to get a description of the assailant\n");
break;
}
printf("Were there any witnesses to the incident? (Y/N)\n");
scanf(" %[^\n]s", &wit_qu);
while ( wit_qu == 'Y' || wit_qu == 'y')
{
printf(" Enter the witnesses name?\n");
fgets(wit_name, 20, stdin);
printf(" Enter the witnesses contact number?\n");
fgets(wit_contact_number, 12, stdin);
break;
}
printf(" Was the assailant armed? (Y/N)\n");
fgets(armed_qu, 3, stdin);
while ( *armed_qu == 'Y' || armed_qu == 'y')
{
printf(" Please describe what the assailant was armed with?\n");
fgets(weapon_description, 50, stdin);
break;
}
printf(" \nPlease enter yours details when prompted\n");
printf(" \nPlease enter your First Name\n");
scanf("%s", first_name);
printf(" \nPlease enter your Surname\n");
scanf("%s", surname);
printf(" \nPlease enter yours Date of Birth, format DD/MM/YYYY\n");
scanf("%d/%d/%d", &dd,&mm,&yy);
if(yy>=1900 && yy<=2018)
{
//check month
if(mm>=1 && mm<=12)
{
//check days
if((dd>=1 && dd<=31) && (mm==1 || mm==3 || mm==5 || mm==7 || mm==8 || mm==10 || mm==12))
printf("Date is valid\n");
else if ((dd>=1 && dd<=30) && (mm==4 || mm==6 || mm==9 || mm==11))
printf("date is valid\n");
else if ((dd>=1 && dd<=28) && (mm==2))
printf("Date is valid.\n");
else if ((dd==29 && mm==2 && (yy%400==0 || yy%4==0 && yy%100!=0)))
printf("Date is valid.\n");
else
printf("Date is invalid.\n");
}
}
mo:
printf("\nEnter Contact Number +44");
while ( !scanf("%lli",&contact_number))
{
fflush(stdin);
printf("\n Invalid Contact Number:\n\n");
printf(" Enter Contact Number Again : ");
}
if (contact_number < 1000000000 || contact_number > 9999999999)
{
printf("\n Please Enter only 10 digits.....\n");
goto mo;
}
printf(" Victims Details\n");
printf(" Full Name : %s %s \n", first_name, surname);
printf(" DOB : %d/%d/%d \n", dd,mm,yy);
printf(" Contact Number : +44%lld \n", contact_number);
printf(" Witness Details\n");
printf(" Full Name : %s\n", wit_name);
printf(" Contact Number : +44%lln\n", wit_contact_number);
printf(" Assailant Details\n");
printf(" Full Name : %s\n", assailant_name);
printf(" Address : %s\n", assailant_address);
printf(" Incident Details\n");
printf(" Date of Incident : %d/%d/%d \n", incident_day,incident_month, incident_year);
printf(" Time of Incident : %d:%d\n", incident_hour, incident_minute);
printf(" Street No. of Incident : %s\n", incident_address_house_no);
printf(" Address of Incident : %s\n", incident_address_street);
printf(" Postcode of Incident : %s\n", incident_address_postcode);
printf(" Was the Assailant Armed: %s\n", armed_qu);
printf(" Description of Weapon : %s\n", weapon_description);
return 0;
}
【问题讨论】:
-
首先,不要使用
goto和标签来代替循环。 -
在同一个程序中同时使用
fgets()和scanf()会导致麻烦。最好只使用fgets()。 -
其次,你使用了
%[scanf格式错误。后面不是s,这使得scanf想要匹配输入中的实际s字符。 -
你使用
scanf和%[格式的另一个问题是%[用于读取null-terminated字符串,并且您提供单个字符作为参数。这意味着scanf将从您提供的字符开始向内存写入(至少)两个 字符。越界写入会导致undefined behavior。