Search theo tên có trong file và in ra các records của tên được search

Mình muốn viết 1 function có chức năng tìm tên ở trong 1 file text và in ra các thông tin của nhân vật mình search nhưng hiện tại mình chưa có ý tưởng viết như thế nào hay nên mong các bác gợi ý!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define MAX_LENGTH 100

struct student
{
	char code[MAX_LENGTH];
	char name[MAX_LENGTH];
	char bdate[MAX_LENGTH];
	double point;
}a;

void listing(struct student a)
{
	int i;
	char x;
	char check;
	FILE *fp;
	
	fp = fopen("Student.txt", "a+");
	if(fp == NULL)
	{
		printf("File doesn't exit.");
		exit(0);
	}
	
	while(1)
	{
		printf("Enter new student:\n");
		printf("Student code: ");
		fgets(a.code, sizeof a.code, stdin);
		setbuf(stdin, NULL);
		printf("Student name: ");
		fgets(a.name, sizeof a.name, stdin);
		setbuf(stdin, NULL);
		printf("Date of birth: ");
		fgets(a.bdate, sizeof a.bdate, stdin);
		setbuf(stdin, NULL);
		printf("Learning point: ");
		while(((scanf("%lf%c", &a.point, &x) != 2 || x != '\n') && clear_stdin()) || a.point < 0 || a.point > 10)
		{
			printf("Invalid input, try again!\n");
			printf("Learning point: ");
		}
		fwrite(&a, sizeof a, 1, fp);
		printf("Press enter to continue, Esc to return the main menu");
		check = fgetc(stdin);
		if(check == '\n')
		{
			continue;
		}
		else if(check == '1')
		{
			break;
		}
		check = getchar();
	}
	fclose(fp);
}

void search_name(struct student a)
{
	FILE *fp;
	
	
	fp = fopen("Student.txt", "r");
	
}

void display(struct student a)
{
	int i, n;
	FILE *fp;
	
	fp = fopen("Student.txt", "r");
	
	printf("Student list:\n");
	printf("---------------------------\n");
	while(fread(&a, sizeof a, 1, fp) > 0)
	{
		printf("Student code: %s\nStudent name: %s\nDate of birth: %s\nLearning point: %.1lf\n", a.code, a.name, a.bdate, a.point);
		printf("---------------------------\n");
	}
	printf("\n");
	fclose(fp);
}

int clear_stdin()
{
	while(getchar() != '\n');
	return 1;
}

int main()
{
	int choice, n = 0;
	char c;
	FILE *fp;
	
	
    while(1)
    {
    	
        printf("1) Enter student list\n");
	    printf("2) Look up student\n");
	    printf("3) Display student list\n");
	    printf("4) Exit\n\n");
	    printf("Please choose menu (1->4): ");
	    while(((scanf("%d%c", &choice, &c) != 2 || c != '\n') && clear_stdin()) || choice > 4 || choice < 1)
	    {
		    printf("Invalid input, try again!\n\n");
		    printf("1) Enter student list\n");
	        printf("2) Look up student\n");
	        printf("3) Display student list\n");
	        printf("4) Exit\n\n");
	        printf("Please choose menu (1->4): ");
	    }
	    
	    switch(choice)
	    {
	    	case 1:
	    		listing(a);
	    		break;
	    	case 2:
	    		search_name(a);
	    		break;
	    	case 3:
	    		display(a);
	    		break;
	        case 4:
	        	exit(0);
	        	break;
	    }
    }
    
    return 0;
}

Giống như hàm display() thôi.
Thay vì hiển thị tất cả thì bây giờ so sánh tên (a.name), nếu đúng thì in ra.

3 Likes

Nhưng làm thế nào để nó đi check từng tên 1 với cả so sánh string kiểu gì ạ .

Nếu ý định là tìm chính xác theo họ và tên thì chỉ cần dùng strcmp() để so sánh.

Còn nếu tìm tương đối theo họ hoặc tên thì dùng hàm strtok() để tách từng phần của tên ra rồi so sánh bằng hàm strcmp().

Hoặc bạn tự viết hàm dùng vòng lặp để lặp qua tùng kí tự để so sánh.

4 Likes

Hoặc có thể dùng strstr() cũng được, khỏi phải tách họ và tên cho đỡ mệt. :laughing:

3 Likes

mình viết được như sau rồi nhưng nó vẫn không in records cho mình :

void search_name(struct student a)
{
	FILE *fp;
	int ret;
	char *token;
	const char delim[2] = " ";
	char input[MAX_LENGTH];
	
	fp = fopen("Student.txt", "r");
	if(fp == NULL)
	{
		printf("File doesn't exit.");
		exit(0);
	}
	
	printf("Please enter student name: ");
	fgets(input, sizeof input, stdin);
	setbuf(stdin, NULL);
	
	
	if(fread(&a, sizeof a, 1, fp) == 0)
	{
		printf("No students has been entered to the file.\n");
	}
	
	while(fread(&a, sizeof a, 1, fp) > 0)
	{
		token = strtok(a.name, delim);
		while(token != NULL)
		{
			if(strcmp(input, a.name) == 0)
			{
				printf("Student code: %s\nStudent name: %s\nDate of birth: %s\nLearning point: %.1lf\n", a.code, a.name, a.bdate, a.point);
			}
		}
	}
	
	fclose(fp);
}

chỗ nào chưa ổn bạn chỉ mình với !

Chỗ if của bạn nó sẽ lấy mất một element trong fp rồi. Vd nếu file của bạn có lưu 1 student thì qua if nó sẽ đúng nhưng đến while lại sai, vì fread() trả về 0 do bạn đã lấy 1 ở lần if trước đó.

Phải là strcmp(intput, token)

Do bạn dùng strtok() nên a.name sẽ bị cắt và chỉ còn lại phần họ.

Bạn có thể dùng strstr() như sau:

while(fread(&a, sizeof(a), 1, fp) > 0)
	{
        token = strstr(a.name, input);
        if (token != NULL) {
            printf("Student code: %s\nStudent name: %s\nDate of birth: %s\nLearning point: %.1lf\n", a.code, a.name, a.bdate, a.point);
		}
	}

Nhớ bỏ phần if nha. Nếu vẫn muốn thông báo không tìm thấy thì bạn có thể set một biến count để đếm số học sinh tìm thấy, bằng 0 thì in ra k tìm thấy, khác 0 thì thôi. :smile:

3 Likes

Cảm ơn bạn nhiều nhé, cả 2 solution đều chạy được tốt . Thank :heart_eyes::heart_eyes:

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?