30/09/2018, 16:28

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]=='')
        break;
    fprintf(fp,"%s
", 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("
Danh sach sap xep kieu Viet Nam:
");
    for(i=0; i<n; i++){
        printf("%d . %s
", 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)= '';
    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;
}
Nguyễn Minh Dũng viết 18:40 ngày 30/09/2018

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é

Làm sao để có thể hiển thị syntax highlighting bằng markdown? Các bạn phải đánh dấu ``` như ví dụ dưới đây Chú ý, dấu ``` được tạo ra bởi nút nằm bên trái số 1 trên bàn phím, nút này sẽ là ~ khi bấm giữ Shift Ví dụ cho C Nội dung: ``` void main() { } ``` Và đừng quên ``` ở cuối Kết quả void main() { } Ví dụ cho Pascal Nội dung: ``` Program HelloWorld; Begin WriteLn('Hello world!') {no ";" is required after the last statement of a block - adding one adds a "null stateme…

Ví dụ

```
int countLines(char *filename);
```
Pham Van Quan viết 18:38 ngày 30/09/2018

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

Nguyễn Minh Dũng viết 18:30 ngày 30/09/2018

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

Pham Van Quan viết 18:29 ngày 30/09/2018

Em đã sử lại thành

int countLines(FILE *filename);

nhưng vẫn bị runtime error.

Pham Van Quan viết 18:29 ngày 30/09/2018

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.

Nguyễn Minh Dũng viết 18:41 ngày 30/09/2018

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

```
code ở đây
```
Pham Van Quan viết 18:34 ngày 30/09/2018

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;
}

Pham Van Quan viết 18:29 ngày 30/09/2018

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

Nguyễn Minh Dũng viết 18:30 ngày 30/09/2018

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

#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

Pham Van Quan viết 18:39 ngày 30/09/2018

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;
}

Nguyễn Minh Dũng viết 18:33 ngày 30/09/2018

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);
            }
        }
    }
Pham Van Quan viết 18:35 ngày 30/09/2018

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

Nguyễn Minh Dũng viết 18:34 ngày 30/09/2018

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

Pham Van Quan viết 18:42 ngày 30/09/2018

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.

Nguyễn Minh Dũng viết 18:29 ngày 30/09/2018

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.

Pham Van Quan viết 18:29 ngày 30/09/2018

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;
}

Pham Van Quan viết 18:39 ngày 30/09/2018

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

Nguyễn Minh Dũng viết 18:35 ngày 30/09/2018

Post luôn solution đi chuối ơi. Lúc nãy tính làm cho em mà quên mất. Hehe

Pham Van Quan viết 18:33 ngày 30/09/2018

Em dùng một hàm cắt tên sau đó dùng strcat() nối thêm họ vào sau cuối cùng cũng đơn giản hơn.

#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();
    sortByVietnam();
    sortByEnglish();
    getchar();
    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][40], 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]));
        strcat(name[j], danhSach[j]);
    }

    for (i = 0; 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);

                strcpy(t, name[j - 1]);
                strcpy(name[j - 1], name[j]);
                strcpy(name[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;
}
Nguyễn Minh Dũng viết 18:44 ngày 30/09/2018

Anh chỉ mong sao diễn đàn mình có thêm nhiều thảo luận như thế này nữa. Mặc dù chỉ có mình em làm và nghiên cứu giải pháp cho chính em. Nhưng đó là cách anh muốn diễn đàn mình phát triển.

Các thành viên nỗ lực tìm giải pháo cho mình với sự giúp đỡ của người khác, để rồi sau đó có được lời giải và chia sẻ lại cho người khác.

Topic này đã hoàn thành xuất sắc nhiệm vụ. Anh sẽ close nó sau 1h nữa.

Bài liên quan
0