我一直试图用我有限的知识调试这个程序,并将它与其他程序进行了比较,在这些程序中,我使用了相同的方法来检索文件名以供打开。然而,由于某种奇怪的原因,程序似乎没有收到用户对文件名的输入,有时会陷入某种难以捉摸的循环中。
我同时使用了以下两种:scanf("%s\n",文件名);
以及:gets(文件名);
(我知道get是"危险的",但这是一个不会分发的程序,它是大学级别课堂上的作业)
这是main()函数和getssn()函数(它确实成功地获得了用户输入):
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAXS 19
#define MAXR 999
//structure defining a given client
typedef struct person {
unsigned int ssn, age, height, weight, income;
char name[MAXS+1], job[MAXS+1], religion[MAXS+1], major[MAXS+1], minor[MAXS+1], gender;
}PERSON;
//get and check for ssn validity
int getssn(){
int num;
printf("nSSN: ");
scanf("%d", &num);
if(num<=99999999 || num>999999999){
printf("nPlease input a valid SSN.n");
return 0;
}
else
return num;
}
//read the specified file and check for the input ssn
int readfile(FILE *fptr, PERSON **rptr, int *count){
int v=0, i, j;
char n2[MAXS+1], b[2]=" ";
for(i=0; i<MAXR; i++){
j=i;
//read the file in chunks
if(fscanf(fptr, "%cn%dn%19s %19sn%dn%19sn%dn%19sn%19sn%dn%dn%19snn",
&rptr[j]->gender, &rptr[j]->ssn, rptr[j]->name, n2, &rptr[j]->age,
rptr[j]->job, &rptr[j]->income, rptr[j]->major, rptr[j]->minor,
&rptr[j]->height, &rptr[j]->weight, rptr[j]->religion)==EOF)
i=MAXR;
//make first and last name one element
strcat(rptr[j]->name, b);
strcat(rptr[j]->name, n2);
//if we find a match, tell main the id
if(rptr[MAXR]->ssn==rptr[j]->ssn)
v=j;
}
//count how many clients we have
*count=j;
return v;
}
//commpare age and income
int cmpai(PERSON rec1, PERSON rec2){
int a=0, inc=0;
if(rec1.age<=(rec2.age+10) && rec1.age>=(rec2.age-10))
a=1;
if(rec1.income<=(rec2.income+10000) && rec1.income>=(rec2.income-10000))
inc=1;
if(a==1 && inc==1)
return 1;
else
return 0;
}
//compare hobbies
int cmph(PERSON rec1, PERSON rec2){
if(strcmp(rec1.major,rec2.major)==0 && strcmp(rec1.minor, rec2.minor)==0)
return 1;
else
return 0;
}
//compare weight, height, and religion
int cmpwhr(PERSON rec1, PERSON rec2){
int w=0, h=0, r=0;
double n1, n2;
n1=rec1.height;
n2=rec2.height;
if(n1<=(n2*1.1) && n1>=(n2*0.9))
h=1;
n1=rec1.weight;
n2=rec2.weight;
if(n1<=(n2*1.1) && n1>=(n2*0.9))
w=1;
if(strcmp(rec1.religion, rec2.religion)==0)
r=1;
if(r==1 && h==1 && w==1)
return 1;
else
return 0;
}
//sort the ids in ascending order by ssn for proper output
void sort(int *A, int count){
int i, j, temp;
for(i=0; i<count; i++)
for(j=0; j<count; j++)
if(A[i+1]<A[i]){
temp=A[i];
A[i]=A[i+1];
A[i+1]=temp;
}
}
//display the possible matches in ascending ssn order
void display(int matches[], PERSON rec[], int count){
int i;
for(i=0; i<count; i++){
if(matches[i]==rec[i].ssn)
printf("%sn", rec[i].name);
}
}
int main(){
int valid=-1, i, counter=0, *c=&counter, id[MAXR-1], totalmatches;
char filename[MAXS];
FILE *fp;
PERSON record[MAXR+1], *rp[MAXR+1];
//get a ssn from the user
do{
record[MAXR].ssn=getssn();
}while(record[MAXR].ssn==0);
//get a filename
printf("Name of file of records: ");
scanf("%s", filename);
printf("%s", filename);
//open the file, if possible
if((fp=fopen(filename, "r"))==NULL)
perror(filename);
else{
printf("test");
for(i=0; i<=MAXR; i++){
rp[i]=&record[i];
id[i]=0;
}
//read the file, find the matching ssn
valid=readfile(fp, rp, c);
//check if the ssn is in the file, if not tell the user
if(valid<0){
printf("nSSN %d is not found in file %s.n", record[MAXR].ssn, filename);
return EXIT_FAILURE;
}
else {
//check for matches and count how many we have
for(i=0; i<counter; i++){
if(i!=valid)
if(record[valid].gender!= record[i].gender)
if(cmpai(record[valid], record[i])==1 || cmph(record[valid], record[i])==1 || cmpwhr(record[valid], record[i])==1){
id[i]=record[i].ssn;
totalmatches+=1;
}
}
//if we have matches sort them and display them, otherwise tell the user he has no match in this group
if(totalmatches>0){
sort(id, counter);
display(id, record, counter);
}
else
printf("nNo matches.n");
fclose(fp);
return EXIT_SUCCESS;
}
}
}
这是当前输入(单引号)/输出:
run
[Switching to process 6956]
Running…
SSN: '111223333'
Name of file of records: 'clients.txt'
clients.txttest
Debugger stopped.
Program exited with status value:0.
您应该使用getssn()函数。你需要填写一份报税表。
int getssn(){
int num;
printf("nSSN: ");
scanf("%d", &num);
return num; // You MUST put this in.
}
这将改进此代码:
do{
record[MAXR].ssn=getssn();
}while(record[MAXR].ssn==0);
如果您忘记了返回,那么getssn()可能永远返回0。
您还应该告诉我们您看到的精确输出。您还应该将所有输出复制到您的问题中。
永远不要使用任何scanf
函数族;它们并不能让您对无效输入所发生的事情有足够的控制权,而scanf("%s")
和gets
一样危险。
但这可能不是你眼前的问题。当文件不在当前工作目录中时,更可能是尝试通过部分路径名打开文件。尝试键入完整的路径名(/home/kabir/filename
、C:userskabirfilename
,诸如此类)。此外,更改
printf("nCould not open filen");
至
perror(filename);
会在出现问题时为您提供更多信息。
应该是
scanf("%s", filename)
即移除n
无关,但您似乎忘记了getssn()
末尾的return num
。
查看您当前的代码(都柏林/伦敦时间晚上8:10),您应该使用以下代码:
//get a filename
printf("Name of file of records: ");
//scanf("%s", filename);
printf("scanned file: <%s>n", filename);
//open the file, if possible
if((fp=fopen(filename, "r"))==NULL)
perror(filename);
else{
printf("testn");
...