sắp xếp tên theo alphabe trong Tiếng Vệt

Chào mọi người.
Em đang viết một chương trình C nhập vào họ tên từ bàn phím và lưu danh sách ra file, ( có thể nhập tiếp tục ghi thêm vào cuối file) sau đó sắp xếp và in ra màn hình. Khi em chạy chương trình thì bị lỗi runtime. Mọi người giúp em với ạ. Đây là code của em:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5000

char *subString(char *string, int position, int endstr);
//Lấy tên từ họ tên đầy đủ
char *getName(char* fullName);
//đếm số dòng đã nhập trong file
int countLines(char *filename);

void sortByVietnam();

void nhapDanhSach();

int main(){
    nhapDanhSach();
    sortByVietnam();
    return 0;
}

void nhapDanhSach(){
    int i=0;
    char danhSach[5000][30];
    FILE *fp;
    fp=fopen("D:\\danhsach.txt", "a+");

    //Nhap danh sach.
    i= countLines(fp);

    while(i<5000){
    printf("Nhap ho ten sinh vien thu %d:", i+1);
    gets(danhSach[i]);    fflush(stdin);
    if(danhSach[i][0]=='\0')
        break;
    fprintf(fp,"%s\n", danhSach[i]);
    i++;
    }
    fclose(fp);
};

void sortByVietnam(){
   char name[5000][30], danhSach[5000][30], *tg;
    int i=0, j=0;
    FILE* fp = fopen("D:\\danhsach.txt", "r");
    //read file input assign to danhsach
    while (fgets(danhSach[i], 30 , fp)){
        i++;
    }

    int n=strlen(danhSach);

    for(i=0; i< n; i++){
        strcpy(name[i], getName(danhSach[i]));
    }

    for(i=0; i<n-1; i++){
		for(j=i+1; j<n; j++){
			if(strcmp(name[i], name[j])>0){
				strcpy(tg, danhSach[i]);
				strcpy(danhSach[i], danhSach[j]);
				strcpy(danhSach[j], tg);
			}
            if(strcmp(name[i],name[j])==0&&strcmp(danhSach[i], danhSach[j])>0){
                strcpy(tg, danhSach[i]);
				strcpy(danhSach[i], danhSach[j]);
				strcpy(danhSach[j], tg);
            }
        }
    }
    printf("\nDanh sach sap xep kieu Viet Nam:\n");
    for(i=0; i<n; i++){
        printf("%d . %s\n", i+1, danhSach[i]);
    }
};


char *subString(char *string, int start, int endstr){

    int c, length;
    length = endstr-start+1;
    char *pointer = (char*)malloc(sizeof(char)*(length+1));

    for (c = 0 ; c < start ; c++)
        string++;

    for (c = 0 ; c < length; c++){
        *(pointer+c) = *string;
        string++;
    }
    *(pointer+c)= '\0';
    return pointer;
}

char *getName(char* fullName){
    char*name;
    int i, n =strlen(fullName);
    for(i= n-1; i>0; i--){
        if(fullName[i]==' '){
          name=(subString(fullName, i+1, n-1));
          break;
        }
    }
    return name;
};

int countLines(char* filename){
    FILE *fp=NULL;
    fp=fopen("D:\\danhsach.txt", "r");
    char str[MAX+1];
    int numLine;
    numLine = 0;
    while( fgets(str, MAX, fp)!= NULL ){
        numLine++;
    }
    return numLine;
}
1 Like

Dòng này có vấn đề @ChuoiTieu ơi

i= countLines(fp);

Em khai báo hàm countLines nhận vào chuỗi cơ mà.

int countLines(char *filename);

P/S: Lần sau sử MarkDown để post code nhé

Ví dụ

```
int countLines(char *filename);
```
1 Like

Vâng, Cảm ơn anh Đạt. Để em sửa lại xem sao.

Đấy chỉ là một lỗi thôi @ChuoiTieu, anh nghi ngờ có nhiều lỗi hơn đấy.

1 Like

Em đã sử lại thành

int countLines(FILE *filename);

nhưng vẫn bị runtime error.

bác bật debug lên rồi xem thử lỗi runtime nó xảy ra ở dòng code nào chứ, xem thử rồi tới code đó sửa là đc, đợi chốc mình bật debug thử xem.

1 Like

em sửa hết runtime rồi ạ Nhưng mà tên sắp xếp in ra không đúng alphabe.
Đang debug tìm lỗi.

okie, vậy là gọn :smile: tính tới giờ là 5p cái máy mình đang open solution =))

@ChuoiTieu gửi lên code mới cập nhật đi, nhớ dùng markdown nhé

```
code ở đây
```
1 Like

Code mới đây của em đây ạ

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5000

char *subString(char *string, int position, int endstr);

char *getName(char* fullName);

int countLines(FILE *fp);

void sortByVietnam();

void nhapDanhSach();

int main(){
    nhapDanhSach();
    sortByVietnam();
    return 0;
}

void nhapDanhSach(){
    int i=0;
    char danhSach[5000][30];
    FILE *fp;
    fp=fopen("D:\\danhsach.txt", "a+");

    //Nhap danh sach.

    i= countLines(fp);

    while(i<5000){
    printf("Nhap ho ten sinh vien thu %d:", i+1);
    gets(danhSach[i]);    fflush(stdin);
    if(danhSach[i][0]=='\0')
        break;
    fprintf(fp,"%s\n", danhSach[i]);
    i++;
    }
    fclose(fp);
};

void sortByVietnam(){
   char name[5000][30], danhSach[5000][30], *tg=NULL;
    int i=0, j=0;
    FILE* fp = fopen("D:\\danhsach.txt", "r");
    //read file input assign to danhsach
    while (fgets(danhSach[i], 30 , fp)){
        i++;
    }

    int k=i;

    int row = sizeof(danhSach)/sizeof(danhSach[0]);
    int column = sizeof(danhSach[0])/row;

    int n=column;

    for(j=0; j< n; i++){
        strcpy(name[i], getName(danhSach[i]));
    }

    for(i=0; i<n; i++){
		for(j=i+1; j<n; j++){
			if(strcmp(name[i], name[j])>0){
				strcpy(tg, danhSach[i]);
				strcpy(danhSach[i], danhSach[j]);
				strcpy(danhSach[j], tg);
			}
            if(strcmp(name[i],name[j])==0&&strcmp(danhSach[i], danhSach[j])>0){
                strcpy(tg, danhSach[i]);
				strcpy(danhSach[i], danhSach[j]);
				strcpy(danhSach[j], tg);
            }
        }
    }
    printf("\nDanh sach sap xep kieu Viet Nam:\n");
    for(i=0; i<k; i++){
        printf("%d %s\n", i+1, danhSach[i]);
    }
};


char *subString(char *string, int start, int endstr){

    int c, length;
    length = endstr-start+1;
    char *pointer = (char*)malloc(sizeof(char)*(length+1));

    for (c = 0 ; c < start ; c++)
        string++;

    for (c = 0 ; c < length; c++){
        *(pointer+c) = *string;
        string++;
    }
    *(pointer+c)= '\0';
    return pointer;
}

char *getName(char* fullName){
    char*name;
    int i, n =strlen(fullName);
    for(i= n-1; i>0; i--){
        if(fullName[i]==' '){
          name=(subString(fullName, i+1, n-1));
          break;
        }
    }
    return name;
};

int countLines(FILE *fp){
    fp=NULL;
    fp=fopen("D:\\danhsach.txt", "r");
    char str[MAX+1];
    int numLine;
    numLine = 0;
    while( fgets(str, MAX, fp)!= NULL ){
        numLine++;
    }
    return numLine;
}

Em nghĩ mình sai ở phần hoán đổi 2 tên với nhau. Vì mảng giống như hằng.

Có thể giải thuật của em chưa đúng, anh google thì thấy có solution này, em so sánh với cái của em đang dùng thử. Code em dùng vòng for loop khá khó hiểu :smile:

#include<stdio.h>
#include<string.h>

void main() {
    char s[5][20], t[20];
    int i, j;
    clrscr();

    printf("\nEnter any five strings : ");
    for (i = 0; i < 5; i++)
        scanf("%s", s[i]);

    for (i = 1; i < 5; i++) {
        for (j = 1; j < 5; j++) {
            if (strcmp(s[j - 1], s[j]) > 0) {
                strcpy(t, s[j - 1]);
                strcpy(s[j - 1], s[j]);
                strcpy(s[j], t);
            }
        }
    }

    printf("\nStrings in order are : ");
    for (i = 0; i < 5; i++)
        printf("\n%s", s[i]);

    getch();
}

Output:

Enter any five strings :
pri
pra
pru
pry
prn
Strings in order are :
pra
pri
prn
pru
pry

Nguồn: http://www.c4learn.com/c-programs/c-program-to-sort-set-of-strings-in-alphabetical-order-using-strcmp.html

1 Like

Em cũng đã thử code theo giải thuật này (sắp xếp theo kiểu tiếng anh) nhưng vẫn không sắp xếp được

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5000

char *subString(char *string, int start, int endstr);

char *getName(char* fullName);

int countLines(FILE *fp);

void sortByVietnam();

void nhapDanhSach();

int main(){
    nhapDanhSach();
    sortByVietnam();
    return 0;
}

void nhapDanhSach(){
    int i=0;
    char danhSach[5000][30];
    FILE *fp;
    fp=fopen("D:\\danhsach.txt", "a+");

    //Nhap danh sach.

    i= countLines(fp);

    while(i<5000){
    printf("Nhap ho ten sinh vien thu %d:", i+1);
    gets(danhSach[i]);    fflush(stdin);
    if(danhSach[i][0]=='\0')
        break;
    fprintf(fp,"%s\n", danhSach[i]);
    i++;
    }
    fclose(fp);
};

void sortByVietnam(){
   char name[5000][30], danhSach[5000][30], tg[30];
    int i=0, j=0;
    FILE* fp = fopen("D:\\danhsach.txt", "r");
    //read file input assign to danhsach
    while (fgets(danhSach[i], 30 , fp)){
        i++;
    }

    int k=i;

    int row = sizeof(danhSach)/sizeof(danhSach[0]);
    int column = sizeof(danhSach[0])/row;

    int n=column;

    for(j=0; j< n; i++){
        strcpy(name[i], getName(danhSach[i]));
    }

    printf("\nDanh sach chua sap xep:\n\n");

    for(i=0; i<k; i++){
        printf("%d %s\n", i+1, danhSach[i]);
    }

    for(i=0; i<n; i++){
		for(j=i+1; j<n; j++){
			if(strcmp(danhSach[i], danhSach[j])>0){
				strcpy(tg, danhSach[i]);
				strcpy(danhSach[i], danhSach[j]);
				strcpy(danhSach[j], tg);
			}
        }
    }
    printf("\nDanh sach sap xep kieu Viet Nam:\n\n");
    for(i=0; i<k; i++){
        printf("%d %s\n", i+1, danhSach[i]);
    }
    fclose(fp);
};


char *subString(char *string, int start, int endstr){

    int c, length;
    length = endstr-start+1;
    char *pointer = (char*)malloc(sizeof(char)*(length+1));

    for (c = 0 ; c < start ; c++)
        string++;

    for (c = 0 ; c < length; c++){
        *(pointer+c) = *string;
        string++;
    }
    *(pointer+c)= '\0';
    return pointer;
}

char *getName(char* fullName){
    char*name;
    int i, n =strlen(fullName);
    for(i= n-1; i>0; i--){
        if(fullName[i]==' '){
          name=(subString(fullName, i+1, n-1));
          break;
        }
    }
    return name;
};

int countLines(FILE *fp){
    fp=NULL;
    fp=fopen("D:\\danhsach.txt", "r");
    char str[MAX+1];
    int numLine;
    numLine = 0;
    while( fgets(str, MAX, fp)!= NULL ){
        numLine++;
    }
    return numLine;
}

Anh thấy giải thuật em dùng đâu giống đâu, trước hết em hiểu giải thuật của cái link anh gửi chưa?

    for(i=0; i<n; i++) {
        for(j=i+1; j<n; j++) {
            if(strcmp(danhSach[i], danhSach[j])>0) {
                strcpy(tg, danhSach[i]);
                strcpy(danhSach[i], danhSach[j]);
                strcpy(danhSach[j], tg);
            }
        }
    }
1 Like

Cảm ơn anh Đạt, Sắp xếp theo kểu tiếng Anh thì chuẩn rồi ạ.
Em đang thay đổi thành sắp xếp theo kiểu tiếng Việt nữa là xong

1 Like

Tiếng Anh hay tiếng Việt cũng giống nhau mà Chuối ơi :smile:

1 Like

Khác mà anh.
Tiếng Việt mình nhập vào tên ở sau cùng , nhưng tiếng anh thì họ ở cuối tên đặt lên trước tiên. Ở đây em sắp xếp họ tên đầy đủ chứ không phải chỉ có tên đâu anh.

  • Giải pháp 1:

Vậy em tìm cách cắt tên và họ riêng ra, lưu ở 2 chuỗi khác nhau. Sau đó so sánh Tên trước, so sánh tên xong. Nếu trùng tên thì so sánh họ. Sau khi so sánh hết thì lưu lại trong mảng với thứ tự hợp lý.

Khi in ra thì in họ trước, tên sau.

  • Giải pháp 2:

Cắt tên đặt lại phía trước họ, lưu tên và họ trong 1 chuỗi, so sánh như tiếng Anh. Khi in ra thì in họ trước, tên sau.

1 Like

Em đã sử dụng một hàm cắt tên sau đó lưu tên vào một mảng để so sánh tên trước, họ và đệm sau nhưng không biết sai ở đâu. Anh Đạt có thể giúp em được không ạ. Chương trình chạy thì không báo lỗi. Có lẽ sai ở phần giải thuật.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5000

char *subString(char *string, int start, int endstr);

char *getName(char* fullName);

int countLines(FILE *fp);

void swapName(char *name, char *name2);

void sortByEnglish();

void sortByVietnam();

void nhapDanhSach();

int main(){
    nhapDanhSach();
    sortByEnglish();
    sortByVietnam();
    return 0;
}

void nhapDanhSach(){
    int i=0;
    char danhSach[5000][30];
    FILE *fp;
    fp=fopen("D:\\danhsach.txt", "a+");

    //Nhap danh sach.

    i= countLines(fp);

    while(i<5000){
    printf("Nhap ho ten sinh vien thu %d:", i+1);
    gets(danhSach[i]);    fflush(stdin);
    if(danhSach[i][0]=='\0')
        break;
    fprintf(fp,"%s\n", danhSach[i]);
    i++;
    }
    fclose(fp);
};

void sortByVietnam(){
   char name[5000][30], danhSach[5000][30], t[30];
    int i=0, j=0;
    FILE* fp = fopen("D:\\danhsach.txt", "r");
    //read file input assign to danhsach
    while (fgets(danhSach[i], 30 , fp)){
        i++;
    }

    int k=i;

    for(j=0; j< k; j++){
        strcpy(name[j], getName(danhSach[j]));
    }

    for (i = 1; i < k-1; i++) {
        for (j = 1; j < k; j++){
            if (strcmp(name[j - 1], name[j]) > 0) {
                strcpy(t, danhSach[j - 1]);
                strcpy(danhSach[j - 1], danhSach[j]);
                strcpy(danhSach[j], t);
            }else
                if(strcmp(name[j-1], name[j])==0&&strcmp(danhSach[j - 1], danhSach[j]) > 0){
                    strcpy(t, danhSach[j - 1]);
                    strcpy(danhSach[j - 1], danhSach[j]);
                    strcpy(danhSach[j], t);
                }
        }
    }
    printf("\nDanh sach sap xep kieu tieng Tieng Viet:\n\n");
    for(i=0; i<k; i++){
        printf("%d %s\n", i+1, danhSach[i]);
    }
    fclose(fp);
};

void sortByEnglish(){
   char name[5000][30], danhSach[5000][30], t[30];
    int i=0, j=0;
    FILE* fp = fopen("D:\\danhsach.txt", "r");
    //read file input assign to danhsach
    while (fgets(danhSach[i], 30 , fp)){
        i++;
    }

    int k=i;

    for(j=0; j< k; j++){
        strcpy(name[j], getName(danhSach[j]));
    }

     for (i = 1; i < k-1; i++) {
        for (j = 1; j < k; j++) {
            if (strcmp(danhSach[j - 1], danhSach[j]) > 0) {
                strcpy(t, danhSach[j - 1]);
                strcpy(danhSach[j - 1], danhSach[j]);
                strcpy(danhSach[j], t);
            }
        }
    }
    printf("\nDanh sach sap xep kieu tieng Anh:\n\n");
    for(i=0; i<k; i++){
        printf("%d %s\n", i+1, danhSach[i]);
    }
    fclose(fp);
};


char *subString(char *string, int start, int endstr){

    int c, length;
    length = endstr-start+1;
    char *pointer = (char*)malloc(sizeof(char)*(length+1));

    for (c = 0 ; c < start ; c++)
        string++;

    for (c = 0 ; c < length; c++){
        *(pointer+c) = *string;
        string++;
    }
    *(pointer+c)= '\0';
    return pointer;
}

char *getName(char* fullName){
    char*name;
    int i, n =strlen(fullName);
    for(i= n-1; i>0; i--){
        if(fullName[i]==' '){
          name=(subString(fullName, i+1, n-1));
          break;
        }
    }
    return name;
};

int countLines(FILE *fp){
    fp=NULL;
    fp=fopen("D:\\danhsach.txt", "r");
    char str[MAX+1];
    int numLine;
    numLine = 0;
    while( fgets(str, MAX, fp)!= NULL ){
        numLine++;
    }
    return numLine;
}

1 Like

Cuối cùng em cũng làm xong rồi. Cảm ơn anh Đạt và mọi người đã giúp đỡ. :smile:

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