Function thay thế cho fflush(stdin)?

mình có môt đoạn code thế này, mình đang học cấp phát động để tạo mảng với struct, đoạn code dưới là để nhạp vào các họ tện người thôi

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

typedef struct {
    char* first_name;
    char* last_name;
}Person;

 int num_people = 0;
    printf("how many people are there?\n");
    scanf("%d",&num_people);
    fflush(stdin);
    Person* person = NULL;
    person = calloc(num_people, sizeof(Person));
    person->first_name = calloc(num_people, sizeof(char));
    person->last_name = calloc(num_people, sizeof(char));
    if(person != NULL) {
        for(int i = 0; i < num_people; ++i) {
            printf("nguoi thu %d\n", i + 1);
            printf("last name : ");
            gets(person[i].last_name); fflush(stdin);
            printf("first name : ");
            gets(person[i].first_name); fflush(stdin);
        }
    }
    else
        printf("failed to get memories\n");
    return 0;
}

dù đã dùng fflush(stdin) bao nhiêu lần nó vẫn bị cái lỗi trôi lệnh, mò ra mới biết ffush(stdin) k phải standard, mọi người có cái hàm nào có thể xóa được buffer thì cho mình biết với. Thanks trước nha.
P/s: đừng đưa cho mình hàm cin.ignore nha, mình đang học c, code ở trên cũng là code c thôi có biết gì về c++ đâu, search thì toàn thấy cin.igonre T_T

mình có đặt một cái fflush(stdin) ở sau cái scanf("%d",&num_people) rồi mà, còn cái fflush(stdin) sau gets là do mình muốn nói về cái "dù đã dùng fflush(stdin) bao nhiêu lần nó vẫn bị cái lỗi trôi lệnh " còn về ++i với i++ đúng là khác nhau nhưng trong trường hợp này nó không ảnh hưởng gì đến chương trình.
.

ham calloc ban chua ep kieu kia

ép kiểu gì bạn ?, hàm calloc nó cần gì cái ép kiểu đâu

person =(Person*) calloc(num_people, sizeof(Person));

ép kiểu thành pointer?, cái person mình khái báo nó là pointer kiểu Person ở dòng trên rồi mà, co thêm vào nó cũng k giải quyết được gì

bạn coi cái cú pháp calloc rồi hiểu, toán tử new nó cũng ép kiểu chứ không gì cái hàm calloc malloc này đâu

con trỏ là nắm giữ địa chỉ, giờ bạn muốn lưu địa chỉ của vùng nhớ đã cấp phát không ép kiểu thì sao nó lưu được @@, bạn thử lưu địa chỉ biến float cho con trỏ int * thử có được không thì sẽ hiểu … có lẽ bạn chưa vững pointer lắm

hai dòng calloc tiếp theo của bạn vẫn sai đấy … cái dấu -> thay thế cho (*person).firts_name nghĩa là tên (giá trị của biến) chứ không phải địa chỉ bạn calloc là trả về 1 con trỏ nữa đấy nhưng ở đây bạn đúng vì thành phần struct là 2 con trỏ

hm trong bộ tài liệu mình học nó không ghi gì về cái vụ ép kiểu này cả, nó nói malloc với calloc trả về một pointer kiêu void* có thể trỏ đến bất kỳ type nào, mình đã thử và thấy k có vấn để gì, tại sao nó lại như vậy nhỉ.
p/s mình đã thử ép kiêu nhưng vẫn khong được

kiểu con trỏ void là kiểu con trỏ bất kì , người ta vẫn ép kiểu void* sang int* hoặc kiểu bạn đang dùng là Person* … lúc trước mình cũng học struct và sấp mặt chỗ này nên mình quay về đọc kĩ con trỏ(chắc coi này kia gần mười mấy lần cả 2 3 tuần mới thông )

vậy sẽ có gì khác nhau giứa calloc, malloc để yên không ép kiểu và có ép kiều

last_name với first _name là hai mảng ký tự, mảng bản chất là 1 pointer trỏ đến cái phần tử đầu tiên của mảng thế nên nó có thể nhận một giá trị là một địa chỉ (theo mình biết thì là thế :sweat_smile: ), nếu k phải vậy thì mình nên ghi lại cái -> thế nào đây ?

thì nó vẫn là 1 con trỏ vô kiểu void * ^^ dòng truy xuất đến thành phần trong struct đấy. thực chất khi calloc malloc new nó sẽ cung cấp 1 vùng nhớ đủ cho cái struct của bạn chứa được dữ liệu sau đó nó sẽ cho bạn 1 cái địa chỉ của vùng nhớ đó…

tóm lại cái calloc bạn xong thì bạn có 1 vùng nhớ chứa và nó chứa 2 con trỏ name … à bạn ép kiểu 2 cái calloc phía dưới nữa nhé (giờ mới để ý bạn tạo 2 thành phần con trỏ trong cái struct của bạn)

" dòng truy xuất đến thành phần trong struct đấy " là ntn vậy bạn, mình cũng ép kiểu hai cái biến name thành char * rồi mà vẫn không được, và nếu không ép keieru malloc, calloc có thể gây ra lỗi gì không

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

typedef struct Person{
    char* first_name;
    char* last_name;
}Person;
int main(){
	
 int num_people = 0;
 
 	
    printf("how many people are there?\n");
    scanf("%d",&num_people);
    
    Person* person = NULL;
    person = (Person*)calloc(num_people, sizeof(Person));
    for(int i = 0; i < num_people; ++i){
    	
    person[i].first_name =(char*) calloc(90, sizeof(char));//cho nay ma num la  sai @@
    person[i].last_name = (char*)calloc(90, sizeof(char));// cho nay cung  vay 
    }
    if(person != NULL) {
        for(int i = 0; i < num_people; ++i) {
            printf("nguoi thu %d\n", i + 1);
            printf("last name : ");
            fflush(stdin);
            gets(person[i].last_name); 
            printf("first name : ");
            fflush(stdin);
            gets(person[i].first_name);
			fflush(stdin); 
        }
    }
    else
       {
       	
        printf("failed to get memories\n");}
    
        
    return 0;
}

ban hong kien thuc cap phat dong nhieu qua … vay la di nguoc lai quy tac daynhauhoc roi day nhung coi nhu ban tham khao va hieu …so 90 trong calloc la do dai cua cai ten minh cho bat ki 90 cho no dai day

ở code của bạn, mình vận không hiểu cái đoạn này làm thế này thì chằng phải ta sẽ cấp phát bộ nhớ cho từng phan tu trong mảng sao, không biết mình sai ở đâu vậy

for(int i = 0; i < num_people; ++i){
    	
    person[i].first_name =(char*) calloc(90, sizeof(char));
    person[i].last_name = (char*)calloc(90, sizeof(char));
    }

và nếu mình thay đoạn code trên cái này thì chương trình sẽ lại bị lỗi, vậy thì mình bị sai kiến thức ở cái đoạn này bạn có thẻ chỉ ra mình sai ở đâu không. Mình học cấp phát động vs struct từ video này bắt đầu từ cái phút 12, anh cũng có đoạn code tương tự thế này và nó cứ run mà chả có lỗi gì

person->first_name = (char*)calloc(30, sizeof(char));
person->last_name = (char*)calloc(30, sizeof(char));

mình biết từ đầu đến giờ bạn đã giúp mình rất nhiểu nhưng lúc này mình thực sự rất hoang mang, mình cứ tưởng đã rành về cấp phát động rồi thế mà giờ hóa ra lại toàn ngộ nhận. Nếu bạn có thể giúp mình thì thật tốt quá, mình thật sự cảm ơn.

vì bạn nhập vào số người sau đó cấp phát theo số người đó nghĩa là bộ nhới sẽ trích ra vùng nhớ đủ cho kiểu dữ liệu Person của bạn giả sử 3 người thì sẽ cấp phát đủ 3sizeof(person).
nhưng trong cái person của bạn có 2 con trỏ char =>> mỗi cái person[i] sẽ có 2 con trỏ char
, lúc này bạn cần cấp phát cho 2 con trỏ này 2 địa chỉ của vùng nhới chứa cá firt name và last name nói thẳng ra là cái mảng (ns lun là Mảng A nghĩa là pointer A với A là địa chỉ phần tử đầu tiên A[0] của mảng) vì vậy mình calloc với 90 phần tử nghĩa là tạo ra cái mảng 90 chứa firtname và cái mảg 90 với last ame mình cho đại ấy mà cái tên nào dài vậy đâu , Và địa chỉ của 2 cái mảng sẽ được lưu trong 2 con trỏ thành phần trong struct …
Mình chạy vòng lặp vì nếu 3 người thì mỗi person[i] đều phải có firtsname và lastname nên tính ra cần phải cấp phát dộng cho mỗi cái person[i] này…
nếu bạn không chạy vòng lặp theo i thì ghi như calloc(num,sizeof(char)) là không có ý nghĩa gì
vì đó là độ dài cái first và lastname của 1 person[i] chứ không phải của cả 1 cái mảng động

mình hiểu đoạn code của bạn rồi, nhưng vẫn còn một thắc mắc
nếu mình code thế này, mình cấp phát luôn cho hai cai con trỏ name của tất cả các cái person 30 * num_people * sizeof(char) (bytes) vì mỗi cái first_name, last_name sẽ có khoảng 30 phấn tử vậy với n người ta sẽ cần n * 30 (bytes) cho tất cả last_name và first_name vậy tại sao nó lại vẫn error nhỉ

person->first_name = (char*)calloc(30 * num_people, sizeof(char));
person->last_name = (char*)calloc(30 * num_people, sizeof(char));
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?