我已经编写了一个可以在单个文件中完美运行的代码,但是当我尝试将代码拆分为两个.c和一个.h文件时,makefile会显示未定义的结构引用,该错误是全局数据。
[有人可以帮助我将此代码拆分为.c和.h文件,以使未定义的引用错误不会弹出并且代码运行平稳
我只需要分开的.c和.h文件,我可以制作.mk文件,我是makefile的初学者任何帮助将不胜感激
这里命令行参数是代码从中读取信息的文件的名称-emplyoyeeinfo.txt
运行makefile(4 .c和1 .h文件)时出现的错误在屏幕快照中链接如下[输出画面] [1] [1]:https://i.stack.imgur.com/Pgr28.jpg
emplyoyeeinfo.txt文件包含这些内容(用户名,ID,密码,休闲,媒体休假,带薪休假)
Ramesh,QW120345,PO56,10,15,7
Rajesh,QW120905,IO56,10,15,7
Kajal,JI456987,IWQ9,10,15,7
Harleen,HJ782013,ZM12,10,15,7
Jim,BN784569,KL45,10,15,7`
请原谅我对这个问题的介绍,我是堆栈溢出和makefile的新手
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
//this code works on ZERO INDEXING
int linematched;//global variable which stores the variable
void main2();//this containsthe main part of the code workings,its pupose is explained below just before the function
void final_print();//prints the details of the user on quitting the wizard
void quit();//this is one function which handles the termination of code prompting the user to take another trail
void again();//this function handles the login if user wishes to take another leave
void table(char file_n[]);//populating the structure from data elements from the file by using specific delimiter
int login();//this function verifies the password with the one present in the file database
int deduction(int linematched,int days,int type_of_leave);//this performs another validation and deducts the days user desires for taking the leave
struct Empdetials
{
char name[25];
char id[9];//onr extra character to store /n
char password[5];
int casual;//casual,medical,earned leave as per the question
int medical;
int earned;
}emp[5];//declaring array of structures which will later be populated using table() function
void main(int argc,char *argv[])//command line arguments takes the name of the file to be read
{
char file_name[30];
strcpy(file_name,argv[1]);
printf("%s\n\n",file_name);
table(file_name);//calling the function to initiate the process of filling a structure with all the data from the files
printf("--------------------------------HELLO-------------------------------\n");
printf("----------------------WELCOME TO LEAVE MANEGMENT SYSTEM--------------\n");
main2();//the use of this is explained below
}
/*main function has a call to table() and invoking main() for re-login used to reset the structure and the deductions were lost,so I copied
everything of the main function into another function called main2() which is basically the amin function without he table() invoking so the
structure is not resetted after every call from again() and quit() during Re-login and structure keeps a track of the deductions that happened and
in this way I also removed the Welcome sentence to the same user,but he main reason is to avoid rewriting of the structure on every call
and losing the deduction data*/
void main2()
{
int casualm=10;//defining the maximum possible leaves here
int medicalm=15;
int earnedm=7;
int leave_days=0;//handles the number of leaves that a user will enter
int choice=0;//type of leave is handled by this variable 1 is casual,2 is emergency,3 is earned
int log=0;//CHECKS IF LOGIN WAS SUCCESFULL OR NOT
int res=0;//CHECKS IF DEDUCTION WAS SUCCESFULL OR NOT
//-------------------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------------------
log=login();//login is invoked and log stores the value which determines wheter the ogin was succesful or not
if(log==1)//if log=1,implies that the login was succesful and the user was found
{
printf("PLEASE SELECT HE TYPE OF LEAVE YOU WANT TO TAKE\n");
printf("1.CASUAL LEAVE\n");
printf("2.MEDICAL LEAVE\n");
printf("3.EARNED LEAVE\n");
scanf("%d",&choice);
printf("PLEASE ENTER THE NUMBER OF LEAVES YOU WANT TO APPLY FOR\n");
scanf("%d",&leave_days);
}
else
{
printf("SORRY THE LOGIN CREDENTIALS DON'T MATCH WITH ANY USER\n\n\n");//when the login fails this message is displayed
again();//gives user another chance to take give the input
}
//first validation of the input values,this ompare the input with the largest value of holidays available
int flag=1;//this controls wheter the variable entetred is within the maximum limit and that decuction() function can be called
if(choice==1)
{
if(leave_days>casualm)
{
printf("THE ENTERED NUMBER OF DAYS CROSSES THE MAXIMUM LIMIT \n");
again();
flag=0;
}
}
else if(choice==2)
{
if(leave_days>medicalm)
{
printf("THE ENTERED NUMBER OF DAYS CROSSES THE MAXIMUM LIMIT \n");
again();
flag=0;
}
}
else if(choice==3)
{
if(leave_days>earnedm)
{
printf("THE ENTERED NUMBER OF DAYS CROSSES THE MAXIMUM LIMIT \n");
again();
flag=0;
}
}
else
{
printf("sorry!! wrong input\n");
again();
flag=0;
}
if(flag)//if the validation is succcesful the value of the variable remains 1 and this loop is entered
{
res=deduction(linematched,leave_days,choice);//if res==1 then thern the validation was succesful and then the deduction is called and parameter is passed
if(res==1)//if deduction was succesful then the
{
printf("DEDUCTION WAS SUCCESFUL\n\n");
again();
//final_print();
}
}
}
//I am trying to convert the file to a structure and then use the structure to access the data and I'm also using files to store the information
extern void table(char file_n[])//this function is responsible for populating the structure by reading the file
{
printf("%s\n\n",file_n);
FILE *fp;//definig a file pointer
char ch;
char line[256];//definig 256 here,any arbitary number can be used
char *token;//token pointer that points to the elements of a line
int tokenposition=0;//token here means the particular text separated by comma
int lineposition=0;//line here is the entire line which has entire details of the an emmployee
fp=fopen(file_n,"r");//opening the file in read mode as we are only accessing information and not rewrting it
//-------------------------------------------------------------------------------------------------------------------------------------------------
while(fgets(line,256,fp) !=NULL) //accessing the lines one by one and trying to recognize the end of a line
{
tokenposition=0;//when we tokenize the line we need the count to keep a track of where we are int he string
//printf("%s \n",line);//used to check which line is not being read by the compiler
token = strtok(line,",");
//this seperates a line into token(entity) based on a delimiter,here the delimiter is a comma
//strtok-tring tokenization method
while(token != NULL)
{
switch(tokenposition)//acessing the required element through the tokenposition counter
{
case 0://NAME
strcpy(emp[lineposition].name,token);
break;
case 1://ID
strcpy(emp[lineposition].id,token);
break;
case 2://PASSWORD
strcpy(emp[lineposition].password,token);
break;
case 3://CASUAL LEAVE
emp[lineposition].casual=atoi(token);
break;
case 4://MEDICAL LEAVE
emp[lineposition].medical=atoi(token);
break;
case 5://EARNED LEAVE
emp[lineposition].earned=atoi(token);
break;
}
token =strtok(NULL,",");
tokenposition++;//to access the next token in the same line
}
lineposition++;//after all the tokens are put in a structure,wwe move to the next line and redo the entire process of reading a line
}
}
int login()
{
int i;//for the loop
char userid[9];//user ID int he majn function,this will be passed to the the login function
char userpassword[5];//user password in the main function
printf("ENTER YOUR 8 CHARACTER USER ID\n");
scanf("%s",userid);
printf("ENTER THE 4 CHARACTER PASSWORD\n");
scanf("%s",userpassword);
linematched=0;
for(i=0;i<5;i++)
{
if((strcmp(emp[i].id,userid)==0)&&(strcmp(emp[i].password,userpassword)==0))//checking if login credentils are corre3ct or wrong
{
linematched=i;
printf("WELCOME %s TO THE LEAVE MANEGMENT SYSTEM\n",emp[linematched].name);
return 1;//TO INDICATE THAT USER WAS FOUND AND LOGIN WAS SUCCESFUL
break;
}
}
}
int deduction(int linematched,int days,int type_of_leave)//here all inputs are validated for the second time after the validation in main function
{
switch(type_of_leave)
{
case 1://casual leave
{
if(days>emp[linematched].casual)
{
printf("SORRY YOU HAVE EXHAUSTED YOUR LEAVE QUOTA\n\n");
again();
return 0;
break;
}
else
{
emp[linematched].casual=emp[linematched].casual-days;
return 1;
break;
}
break;
}
case 2://medical leave
{
if(days>emp[linematched].medical)
{
printf("SORRY YOU HAVE EXHAUSTED YOUR LEAVE QUOTA\n\n");
again();
return 0;
break;
}
else
{
emp[linematched].medical=emp[linematched].medical-days;
return 1;
break;
}
break;
}
case 3://earned leave
{
if(days>emp[linematched].earned)
{
printf("SORRY YOU HAVE EXHAUSTED YOUR LEAVE QUOTA\n\n");
again();
return 0;
break;
}
else
{
emp[linematched].earned=emp[linematched].earned-days;
return 1;
break;
}
break;
};
};
}
void quit()
{
char ans[5];
printf("ARE YOU SURE YOU WANT TO QUIT THE WIZARD? Y OR N\n");
scanf("%s", ans);
if (tolower(ans[0]) == 'y')
{
final_print();
printf("\n\n");
printf("---THANK YOU FOR USING OUR PORTAL--\n");
}
else
{
main2();
}
}
void again()
{
char ans1[5];
printf("SEARCH AGAIN USING ID AND PASSWORD? Y OR N\n");
scanf("%s", ans1);
if (tolower(ans1[0]) == 'y')
{
main2();//FOR RE-LOGIN PROCESS
}
else
{
quit();
}
printf("\n\n\n\n\n\n");
}
void final_print()
{
printf("----------------FINAL STATEMENT OF LEAVE OF EACH EMPLOYEE------------------------\n\n");
int i;
for (i = 0; i < 5; i++)
{
printf("NAME : %s\n",emp[i].name);
printf("USER ID : %s\n",emp[i].id);
printf("CASUAL LEAVE LEFT : %d\n",emp[i].casual);
printf("MEDICAL LEAVE LEFT : %d\n",emp[i].medical);
printf("EARNED LEAVE LEFT : %d\n\n",emp[i].earned);
}
printf("---------THANK YOU FOR USING LEAVE MANEGMENT PORTAL-----\n");
}
使用
struct Empdetials
{
char name[25];
char id[9];//onr extra character to store /n
char password[5];
int casual;//casual,medical,earned leave as per the question
int medical;
int earned;
}emp[5];
您基本上会一步完成两件事:(1)定义struct Empdetials
和(2)定义变量emp
;请注意,至少在打算将此头文件包含在不同的.c文件中的情况下,不能在头文件中define全局变量。
[您将需要将struct Empdetials
的定义,全局变量emp
的声明以及此全局变量的定义以一个翻译单元(即一个.c
文件)分开。请注意extern
中的emp.h
关键字,它声明 emp
将在其他地方(即稍后在emp.c中)被defined一次:
emp.h:
struct Empdetials
{
char name[25];
char id[9];//onr extra character to store /n
char password[5];
int casual;//casual,medical,earned leave as per the question
int medical;
int earned;
};
extern struct Empdetials emp[5];
emp.c:
#include "emp.h"
struct Empdetials emp[5];
int main() { ...
again_final.c:
#include "emp.h"
// Note: no struct Empdetials emp[5]; any more...
again() { ...
login.c:
#include "emp.h"
// Note: no struct Empdetials emp[5]; any more...
login() { ...