为什么我的代码,这是排序和搜索从csv文件,不显示所有的结果,从数据?

erhoui1w  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(82)

我创建了一个程序,包含这样的内容

What Do you want to do? 
1. Display data
2. search data
3. sort data
4. export data
5. exit

字符串
我已经创建了从选项1到选项2的代码,其余的代码仍未构建,因此忽略其余的switch case代码
这是我的代码:

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

typedef struct
{
    char location[100];
    char city[100];
    int price;
    int room;
    int bathroom;
    int carpark;
    char type[100];
    char furnish[100];
} data;

//Quick Sort by location//
void swap(data *a, data *b)
{
    data temp = *a;
    *a = *b;
    *b = temp;
}

int partitionL(data arr[], int low, int high)
{
    char pivot[1000];
    strcpy(pivot, arr[high].location);
    int i = low - 1;

    for (int j = low; j < high; j++)
    {
        if (strcmp(arr[j].location, pivot) < 0)
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return i + 1;
}

void sortL(data arr[], int low, int high)
{
    if (low < high)
    {
        int pi = partitionL(arr, low, high);
        sortL(arr, low, pi - 1);
        sortL(arr, pi + 1, high);
    }
}

/// end of quick sort by location

//Quick Sort by city//

int partitionC(data arr[], int low, int high)
{
    char pivot[1000];
    strcpy(pivot, arr[high].city);
    int i = low - 1;

    for (int j = low; j < high; j++)
    {
        if (strcmp(arr[j].city, pivot) < 0)
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return i + 1;
}

void sortC(data arr[], int low, int high)
{
    if (low < high)
    {
        int pi = partitionC(arr, low, high);
        sortC(arr, low, pi - 1);
        sortC(arr, pi + 1, high);
    }
}

/// end of quick sort by city

//Quick Sort by type//

int partitionT(data arr[], int low, int high)
{
    char pivot[1000];
    strcpy(pivot, arr[high].type);
    int i = low - 1;

    for (int j = low; j < high; j++)
    {
        if (strcmp(arr[j].type, pivot) < 0)
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return i + 1;
}

void sortT(data arr[], int low, int high)
{
    if (low < high)
    {
        int pi = partitionT(arr, low, high);
        sortT(arr, low, pi - 1);
        sortT(arr, pi + 1, high);
    }
}

/// end of quick sort by type

//Quick Sort by furnish//

int partitionF(data arr[], int low, int high)
{
    char pivot[1000];
    strcpy(pivot, arr[high].furnish);
    int i = low - 1;

    for (int j = low; j < high; j++)
    {
        if (strcmp(arr[j].furnish, pivot) < 0)
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return i + 1;
}

void sortF(data arr[], int low, int high)
{
    if (low < high)
    {
        int pi = partitionF(arr, low, high);
        sortF(arr, low, pi - 1);
        sortF(arr, pi + 1, high);
    }
}

/// end of quick sort by furnish

//Quick Sort by price//

int partitionP(data arr[], int low, int high)
{
    int pivot= arr[high].price;
    int i = low - 1;
  
    for (int j = low; j < high; j++)
    {
        if (arr[j].price < pivot)
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return i + 1;
}

void sortP(data arr[], int low, int high)
{
    if (low < high)
    {
        int pi = partitionP(arr, low, high);
        sortP(arr, low, pi - 1);
        sortP(arr, pi + 1, high);
    }
}

/// end of quick sort price

//Quick Sort by room//

int partitionR(data arr[], int low, int high)
{
    int pivot= arr[high].room;
    int i = low - 1;
  
    for (int j = low; j < high; j++)
    {
        if (arr[j].room < pivot)
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return i + 1;
}

void sortR(data arr[], int low, int high)
{
    if (low < high)
    {
        int pi = partitionR(arr, low, high);
        sortR(arr, low, pi - 1);
        sortR(arr, pi + 1, high);
    }
}

/// end of quick sort room

//Quick Sort by bathroom//

int partitionB(data arr[], int low, int high)
{
    int pivot = arr[high].bathroom;
    int i = low - 1;
   
    for (int j = low; j < high; j++)
    {
        if (arr[j].bathroom < pivot)
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return i + 1;
}

void sortB(data arr[], int low, int high)
{
    if (low < high)
    {
        int pi = partitionB(arr, low, high);
        sortB(arr, low, pi - 1);
        sortB(arr, pi + 1, high);
    }
}

/// end of quick sort bathroom

//Quick Sort by carpark//

int partitionK(data arr[], int low, int high)
{
    int pivot = arr[high].carpark;
    int i = low - 1;
   
    for (int j = low; j < high; j++)
    {
        if (arr[j].carpark < pivot)
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return i + 1;
}

void sortK(data arr[], int low, int high)
{
    if (low < high)
    {
        int pi = partitionK(arr, low, high);
        sortK(arr, low, pi - 1);
        sortK(arr, pi + 1, high);
    }
}

/// end of quick sort carpark

// Search location
int searchL(data array[], char target[], int start, int array_length) {
    
    int low = start;
    int high = array_length - 1;
    
    while(low <= high) {
        
        int middle = low + (high - low) / 2;
        char value[100];
        strcpy(value, array[middle].location);
        
        if (strcmp(value, target) < 0)
            low = middle + 1;
        else if (strcmp(value, target) > 0)
            high = middle - 1;
        else
            return middle; //target found
    }
    
    return -1;
}
//end of search location

//Search city
int searchC(data array[], char target[], int start, int array_length) {
    
    int low = start;
    int high = array_length - 1;
    
    while (low <= high) {
        
        int middle = low + (high - low) / 2;
        char value[100];
        strcpy(value, array[middle].city);
        
        if (strcmp(value, target) < 0)
           low = middle + 1;
        else if (strcmp(value, target) > 0)
            high = middle - 1;
        else
           return middle; //target found
    }
    
    return -1;
}
// end of search city

//Search type
int searchT(data array[], char target[], int start, int array_length) {
    
    int low = start;
    int high = array_length - 1;
    
    while (low <= high) {
        
        int middle = low + (high - low) / 2;
        char value[100];
        strcpy(value, array[middle].type);
        
        if (strcmp(value, target) < 0)
           low = middle + 1;
        else if (strcmp(value, target) > 0)
            high = middle - 1;
        else
            return middle; //target found
    }
    
    return -1;
}
// end of search type

//Search furnish
int searchF(data array[], char target[], int start, int array_length) {
    
    int low = start;
    int high = array_length - 1;
    
    while (low <= high) {
        
        int middle = low + (high - low) / 2;
        char value[100];
        strcpy(value, array[middle].furnish);
        
        if (strcmp(value, target) < 0)
            low = middle + 1;
        else if (strcmp(value, target) > 0)
            high = middle - 1;
        else
            return middle; //target found
    }
    
    return -1;
}
// end of search furnish

//search price
int searchP(data array[], int target, int start, int array_length) {
    
    int low = start;
    int high = array_length - 1;
    
    while (low <= high) {
        
        int middle = low + (high - low) / 2;
        int value = array[middle].price;
        
        if (value < target)
            low = middle + 1;
        else if (value > target)
            high = middle - 1;
        else
            return middle; 
    }
    
    return -1;
}
// end of search price

//search room
int searchR(data array[], int target, int start, int array_length) {
    
    int low = start;
    int high = array_length - 1;
    
    while (low <= high) {
        
        int middle = low + (high - low) / 2;
        int value = array[middle].room;
        
        if (value < target)
            low = middle + 1;
        else if (value > target)
            high = middle - 1;
        else
            return middle; 
    }
    
    return -1;
}
// end of search room

//search Bathroom
int searchB(data array[], int target, int start, int array_length) {
    
    int low = start;
    int high = array_length - 1;
    
    while (low <= high) {
        
        int middle = low + (high - low) / 2;
        int value = array[middle].bathroom;
        
        if (value < target)
            low = middle + 1;
        else if (value > target)
            high = middle - 1;
        else
            return middle; 
    }
    
    return -1;
}
// end of search Bathroom

//search carpark
int searchK(data array[], int target, int start, int array_length) {
    
    int low = start;
    int high = array_length - 1;
    
    while (low <= high) {
        
        int middle = low + (high - low) / 2;
        int value = array[middle].carpark;
        
        if (value < target)
            low = middle + 1;
        else if (value > target)
            high = middle - 1;
        else
            return middle; 
    }
    
    return -1;
}
// end of search carpark

int main()
{
    data house[4000];

    FILE *file = fopen("data.csv", "r");
    if(file == NULL){
        printf("File is missing!\n");
        return 1;
    }
    char buffer[1000];
    fgets(buffer, 1000, file);
    char header[1000]; strcpy(header, buffer);

    int n = 0;
    while (fgets(buffer, 1000, file))
    {
        char *token = strtok(buffer, ",");
        strcpy(house[n].location, token);

        token = strtok(NULL, ",");
        strcpy(house[n].city, token);

        token = strtok(NULL, ",");
        house[n].price = atoi(token);

        token = strtok(NULL, ",");
        house[n].room = atoi(token);

        token = strtok(NULL, ",");
        house[n].bathroom = atoi(token);

        token = strtok(NULL, ",");
        house[n].carpark = atoi(token);

        token = strtok(NULL, ",");
        strcpy(house[n].type, token);

        token = strtok(NULL, ",\n");
        strcpy(house[n].furnish, token);

        n++;
    }

    fclose(file);

//  //for checking the output and file processed
//      printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n", "Location", "City", "Price", "Rooms", "Bathroom", "Carpark", "Type", "Furnish");
//      for (int i = 0; i < n; i++)
//      {
//             printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n", house[i].location, house[i].city, house[i].price, house[i].room, house[i].bathroom, house[i].carpark, house[i].type, house[i].furnish);
//      }

    int input = 0;

    do {
        printf("What do you want to do?\n");
        printf("1.  Display data\n");
        printf("2.  Search Data\n");
        printf("3.  Sort Data\n");
        printf("4.  Export Data\n");
        printf("5.  Exit\n");
        printf("Your choice: "); 
        scanf("%d", &input);
    
        switch (input)
        {
          case 1:
            printf("Number of rows: "); 
            int rows;
            scanf("%d", &rows);
            printf("\n");
            printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n", "Location", "City", "Price", "Rooms", "Bathroom", "Carpark", "Type", "Furnish");
            for (int i = 0; i < rows; i++) {
                printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n", house[i].location, house[i].city, house[i].price, house[i].room, house[i].bathroom, house[i].carpark, house[i].type, house[i].furnish);
            }
            printf("\n");
            break;
        
          case 2:
            printf("Choose column: ");
            char column[100];
            scanf("%s", column); 
            printf("What data do you want to find? ");
            char search[100];
            scanf("%s", search);
            
            if (strcmp(column, "Location") == 0) {
                sortL(house, 0, n-1);
                int idx = -1;
                if (searchL(house, search, idx, n ) != -1)
                {   
                    printf("Data Found. Detail of data:\n");
                    printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n", "Location", "City", "Price", "Rooms", "Bathroom", "Carpark", "Type", "Furnish");
                    while((idx = searchL(house, search, idx, n)) != -1){
                        printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n", house[idx].location, house[idx].city, house[idx].price, house[idx].room, house[idx].bathroom, house[idx].carpark, house[idx].type, house[idx].furnish);
                        idx++; 
                    }
                    printf("\n");
                } else {
                    printf("Data Not Found!\n");
                }
            } 
            else if (strcmp(column, "City") == 0) {
                sortC(house, 0, n-1);
                int idx = 0;
                if (searchC(house, search, idx, n ) != -1)
                {
                    printf("Data Found. Detail of data:\n");
                    printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n", "Location", "City", "Price", "Rooms", "Bathroom", "Carpark", "Type", "Furnish");
                    while ((idx = searchC(house, search, idx, n)) != -1){
                        printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n", house[idx].location, house[idx].city, house[idx].price, house[idx].room, house[idx].bathroom, house[idx].carpark, house[idx].type, house[idx].furnish);
                        idx++; 
                    }
                    printf("\n");
                } else {
                    printf("Data Not Found!\n");
                }
            }
            else if (strcmp(column, "Price") == 0) {
                sortP(house, 0, n-1);
                int target = atoi(search);
                int idx = 0;
                if (searchP(house, target, idx, n) != -1) {
                    printf("Data Found. Detail of data:\n");
                    printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n", "Location", "City", "Price", "Rooms", "Bathroom", "Carpark", "Type", "Furnish");
                    while ((idx = searchP(house, target, idx, n)) != -1){
                        printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n", house[idx].location, house[idx].city, house[idx].price, house[idx].room, house[idx].bathroom, house[idx].carpark, house[idx].type, house[idx].furnish);
                        idx++; 
                    }
                    printf("\n");
                }
            }
            else if (strcmp(column, "Rooms") == 0) {
                sortR(house, 0, n-1);
                int target = atoi(search);
                int idx = 0;
                if (searchR(house, target, idx, n) != -1) {
                    printf("Data Found. Detail of data:\n");
                    printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n", "Location", "City", "Price", "Rooms", "Bathroom", "Carpark", "Type", "Furnish");
                    while ((idx = searchR(house, target, idx, n)) != -1){
                        printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n", house[idx].location, house[idx].city, house[idx].price, house[idx].room, house[idx].bathroom, house[idx].carpark, house[idx].type, house[idx].furnish);
                        idx++; 
                    }
                    printf("\n");
                } else {
                    printf("Data Not Found!\n");
                }
            }
            else if (strcmp(column, "Bathroom") == 0) {
                sortB(house, 0, n-1);
                int target = atoi(search);
                int idx = 0;
                if (searchB(house, target, idx, n) != -1) {
                    printf("Data Found. Detail of data:\n");
                    printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n", "Location", "City", "Price", "Rooms", "Bathroom", "Carpark", "Type", "Furnish");
                    while ((idx = searchB(house, target, idx, n)) != -1){
                        printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n", house[idx].location, house[idx].city, house[idx].price, house[idx].room, house[idx].bathroom, house[idx].carpark, house[idx].type, house[idx].furnish);
                        idx++; 
                    }
                    printf("\n");
                } else {
                    printf("Data Not Found!\n");
                }
            }
            else if (strcmp(column, "Carpark") == 0) {
                sortK(house, 0, n-1);
                int target = atoi(search);
                int idx = 0;
                if (searchK(house, target, idx, n) != -1) {
                    printf("Data Found. Detail of data:\n");
                    printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n", "Location", "City", "Price", "Rooms", "Bathroom", "Carpark", "Type", "Furnish");
                    while ((idx = searchK(house, target, idx, n)) != -1) {
                        printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n", house[idx].location, house[idx].city, house[idx].price, house[idx].room, house[idx].bathroom, house[idx].carpark, house[idx].type, house[idx].furnish);
                        idx++; 
                    }
                    printf("\n");
                } else {
                    printf("Data Not Found!\n");
                }
            }
            else if (strcmp(column, "Type") == 0) {
                sortT(house, 0, n-1);
                int idx = 0;
                if (searchT(house, search, idx, n ) != -1)
                {   
                    printf("Data Found. Detail of data:\n");
                    printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n", "Location", "City", "Price", "Rooms", "Bathroom", "Carpark", "Type", "Furnish");
                    while ((idx = searchT(house, search, idx, n)) != -1) {
                        printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n", house[idx].location, house[idx].city, house[idx].price, house[idx].room, house[idx].bathroom, house[idx].carpark, house[idx].type, house[idx].furnish);
                        idx++; 
                    }
                    printf("\n");
                } else {
                    printf("Data Not Found!\n");
                }
            }
            else if (strcmp(column, "Furnish") == 0) {
                sortF(house, 0, n-1);
                int idx = 0;
                if (searchF(house, search, idx, n ) != -1)
                {   
                    printf("Data Found. Detail of data:\n");
                    printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n", "Location", "City", "Price", "Rooms", "Bathroom", "Carpark", "Type", "Furnish");
                    while ((idx = searchF(house, search, idx, n)) != -1) {
                        printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n", house[idx].location, house[idx].city, house[idx].price, house[idx].room, house[idx].bathroom, house[idx].carpark, house[idx].type, house[idx].furnish);
                        idx++; 
                    }
                    printf("\n");
                } else {
                    printf("Data Not Found!\n");
                }
            }
            break;
    
          case 3: 
    
          default:
            break;
        }
    } while (input == 1 || input == 2 || input == 3 || input == 4);
    
    return 0;
}


这是data.csv
显示数据选项工作完美,所以忽略它.搜索数据选项不完美.好的,例如,我尝试搜索城市:Kuala-Lumpur我的程序只显示了12个数据,从数千个实际数据中。其他列也是一样的,比如位置,价格,浴室等。它只是显示最大12个数据。我混淆了。请帮助我找出我的代码有什么问题。这是the image for more detailed explanation,我想说的。非常感谢。

b91juud3

b91juud31#

您的搜索函数不会返回第一个匹配条目,而是返回找到的第一个条目,该条目可能位于一系列匹配条目的中间。您应该以两种方式修改程序:

  • 使搜索函数返回第一个条目
  • 只要满足idx < n和条件,就将while循环改为在条目上搜索。无需再次调用`search,范围有限。

下面是一个修改后的searchL函数:

// Search location
int searchL(data array[], char target[], int array_length) {
    int low = 0;
    int high = array_length;

    while (low < high) {
        int middle = low + (high - low) / 2;
        if (strcmp(array[middle].location, target) < 0)
            low = middle + 1;
        else
            high = middle;
    }
    if (low < array_length && !strcmp(array[low].location, target))
        return low;
    else
        return -1;
}

字符串
下面是main()函数的修改部分:

if (strcmp(column, "Location") == 0) {
            sortL(house, 0, n-1);
            int idx = searchL(house, search, n);
            if (idx != -1) {
                printf("Data Found. Detail of data:\n");
                printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n",
                       "Location", "City", "Price", "Rooms", "Bathroom",
                       "Carpark", "Type", "Furnish");
                while (idx < n && !strcmp(search, house[idx].location)) {
                    printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n",
                           house[idx].location, house[idx].city, house[idx].price,
                           house[idx].room, house[idx].bathroom, house[idx].carpark,
                           house[idx].type, house[idx].furnish);
                    idx++;
                }
                printf("\n");
            } else {
                printf("Data Not Found!\n");
            }
        }


您将大大简化和缩短代码,

  • 使用qsort对数组进行排序,只写一个比较函数
  • 使用所述比较函数来定位给定测试的第一匹配条目。
  • 编写一个实用程序函数来转储数据库,并在适当的地方调用它。

这里有一个简化的版本供您学习:

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

typedef struct {
    char location[100];
    char city[100];
    int price;
    int room;
    int bathroom;
    int carpark;
    char type[100];
    char furnish[100];
} data;

//Comparison functions//
int compare_location(const data *a, const data *b) {
    return strcmp(a->location, b->location);
}

int compare_city(const data *a, const data *b) {
    return strcmp(a->city, b->city);
}

int compare_price(const data *a, const data *b) {
    return (a->price > b->price) - (a->price < b->price);
}

int compare_room(const data *a, const data *b) {
    return (a->room > b->room) - (a->room < b->room);
}

int compare_bathroom(const data *a, const data *b) {
    return (a->bathroom > b->bathroom) - (a->bathroom < b->bathroom);
}

int compare_carpark(const data *a, const data *b) {
    return (a->carpark > b->carpark) - (a->carpark < b->carpark);
}

int compare_type(const data *a, const data *b) {
    return strcmp(a->type, b->type);
}

int compare_furnish(const data *a, const data *b) {
    return strcmp(a->furnish, b->furnish);
}

//Generic Quick Sort for data type//
void data_swap(data *a, data *b)
{
    if (a != b) {
        data temp = *a;
        *a = *b;
        *b = temp;
    }
}

int data_partition(data arr[], int low, int high, int cmp(const data *a, const data *b))
{
    data pivot = arr[high];
    int i = low;

    for (int j = low; j < high; j++) {
        if (cmp(&arr[j], &pivot) < 0) {
            data_swap(&arr[i], &arr[j]);
            i++;
        }
    }
    data_swap(&arr[i], &arr[high]);
    return i;
}

void data_sort(data arr[], int low, int high, int cmp(const data *a, const data *b))
{
    if (low < high) {
        int pi = data_partition(arr, low, high, cmp);
        data_sort(arr, low, pi - 1, cmp);
        data_sort(arr, pi + 1, high, cmp);
    }
}

//Generic Search data
// return -1 if not found
// return index of first match and store index past the last match in *end
int data_search(data array[], int array_length,
                int cmp(const data *a, const data *b),
                const data *target, int *end)
{
    int low = 0;
    int high = array_length;

    while (low < high) {
        int middle = low + (high - low) / 2;
        if (cmp(&array[middle], target) < 0)
            low = middle + 1;
        else
            high = middle;
    }
    for (high = low; high < array_length && !cmp(&array[high], target); high++)
        continue;
    if (low < high) {
        *end = high;
        return low;
    } else {
        *end = -1;
        return -1;
    }
}

// end of search carpark
void dump_rows(data *house, int idx, int end) {
    printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n",
           "Location", "City", "Price", "Rooms", "Bathroom",
           "Carpark", "Type", "Furnish");
    while (idx < end) {
        printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n",
               house[idx].location, house[idx].city, house[idx].price,
               house[idx].room, house[idx].bathroom, house[idx].carpark,
               house[idx].type, house[idx].furnish);
        idx++;
    }
}

//discard rest of input line
int input_flush(void) {
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        continue;
    return c;
}

int main(void)
{
    data house[4000];

    FILE *file = fopen("data.csv", "r");
    if (file == NULL) {
        printf("File is missing!\n");
        return 1;
    }
    char header[1000];
    fgets(header, sizeof header, file);

    char buffer[1000];
    int n = 0;
    while (n < 4000 && fgets(buffer, sizeof buffer, file))
    {
        if (sscanf(buffer, "%99[^,],%99[^,],%d,%d,%d,%d,%99[^,],%99[^,\n]",
                   house[n].location, house[n].city, &house[n].price,
                   &house[n].room, &house[n].bathroom, &house[n].carpark,
                   house[n].type, house[n].furnish) == 8)
        {
            n++;
        }  else {
            printf("invalid record: %s\n", buffer);
        }
    }

    fclose(file);

    //  //for checking the output and file processed
    //  dump_rows(house, 0, n);
    int done = 0;
    while (!done) {
        printf("What do you want to do?\n");
        printf("1.  Display data\n");
        printf("2.  Search Data\n");
        printf("3.  Sort Data\n");
        printf("4.  Export Data\n");
        printf("5.  Exit\n");
        printf("Your choice: ");

        int input;
        int res = scanf("%d", &input);
        input_flush();
        if (res != 1)
            break;

        switch (input)
        {
        case 1:
            printf("Number of rows: ");
            int rows;
            res = scanf("%d", &rows);
            input_flush();
            if (res != 1)
                break;
            printf("\n");
            if (rows > n)
                rows = n;
            dump_rows(house, 0, rows);
            printf("\n");
            break;

        case 2:
            printf("Choose column: ");
            char column[100];
            res = scanf("%99s", column);
            input_flush();
            if (res != 1)
                break;
            data target = { 0 };
            int (*cmp)(const data *a, const data *b) = NULL;

            if (strcmp(column, "Location") == 0) {
                cmp = compare_location;
                printf("What location do you want to find? ");
                res = scanf("%99s", target.location);
            } else
            if (strcmp(column, "City") == 0) {
                cmp = compare_city;
                printf("What city do you want to find? ");
                res = scanf("%99s", target.city);
            } else
            if (strcmp(column, "Price") == 0) {
                cmp = compare_price;
                printf("What price do you want to find? ");
                res = scanf("%d", &target.price);
            } else
            if (strcmp(column, "Room") == 0) {
                cmp = compare_room;
                printf("How many rooms do you want to find? ");
                res = scanf("%d", &target.room);
            } else
            if (strcmp(column, "Bathroom") == 0) {
                cmp = compare_bathroom;
                printf("How many bathrooms price do you want to find? ");
                res = scanf("%d", &target.bathroom);
            } else
            if (strcmp(column, "Carpark") == 0) {
                cmp = compare_carpark;
                printf("How many carparks do you want to find? ");
                res = scanf("%d", &target.carpark);
            } else
            if (strcmp(column, "Type") == 0) {
                cmp = compare_type;
                printf("What location do you want to find? ");
                res = scanf("%99s", target.type);
            } else
            if (strcmp(column, "Furnish") == 0) {
                cmp = compare_furnish;
                printf("What value of furnish do you want to find? ");
                res = scanf("%99s", target.furnish);
            } else {
                printf("unknown column: %s\n", column);
                break;
            }
            input_flush();
            if (res != 1) {
                printf("input error\n");
                break;
            }
            data_sort(house, 0, n-1, cmp);
            int end;
            int idx = data_search(house, n, cmp, &target, &end);
            if (idx != -1) {
                printf("Data Found. Detail of data:\n");
                dump_rows(house, idx, end);
                printf("\n");
            } else {
                printf("Data Not Found!\n");
            }
            break;

        case 3:
        case 4:
            break;
        case 5:
        default:
            done = 1;
            break;
        }
    }
    printf("\n");

    return 0;
}


以下是使用qsort的更高级版本:

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

typedef struct {
    char location[100];
    char city[100];
    int price;
    int room;
    int bathroom;
    int carpark;
    char type[100];
    char furnish[100];
} data;

enum field {
    LOCATION, CITY, PRICE, ROOM, BATHROOM, CARPARK, TYPE, FURNISH, FIELD_NUM, NONE = -1
};

//discard rest of input line
int input_flush(void) {
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        continue;
    return c;
}

enum field get_data_field(void) {
    printf("Choose column: ");
    char column[100];
    int res = scanf("%99s", column);
    input_flush();
    if (res != 1) {
        printf("invalid input\n");
        return NONE;
    }
    if (!strcmp(column, "Location"))
        return LOCATION;
    if (!strcmp(column, "City"))
        return CITY;
    if (!strcmp(column, "Price"))
        return PRICE;
    if (!strcmp(column, "Room"))
        return ROOM;
    if (!strcmp(column, "Bathroom"))
        return BATHROOM;
    if (!strcmp(column, "Carpark"))
        return CARPARK;
    if (!strcmp(column, "Type"))
        return TYPE;
    if (!strcmp(column, "Furnish"))
        return FURNISH;

    int colnum = atoi(column);
    if (colnum > 0 && colnum <= FIELD_NUM)
        return colnum - 1;

    printf("unknown column: %s\n", column);
    return NONE;
}

//Comparison functions//
int compare_location(const void *aa, const void *bb) {
    const data *a = aa;
    const data *b = bb;
    return strcmp(a->location, b->location);
}

int compare_city(const void *aa, const void *bb) {
    const data *a = aa;
    const data *b = bb;
    return strcmp(a->city, b->city);
}

int compare_price(const void *aa, const void *bb) {
    const data *a = aa;
    const data *b = bb;
    return (a->price > b->price) - (a->price < b->price);
}

int compare_room(const void *aa, const void *bb) {
    const data *a = aa;
    const data *b = bb;
    return (a->room > b->room) - (a->room < b->room);
}

int compare_bathroom(const void *aa, const void *bb) {
    const data *a = aa;
    const data *b = bb;
    return (a->bathroom > b->bathroom) - (a->bathroom < b->bathroom);
}

int compare_carpark(const void *aa, const void *bb) {
    const data *a = aa;
    const data *b = bb;
    return (a->carpark > b->carpark) - (a->carpark < b->carpark);
}

int compare_type(const void *aa, const void *bb) {
    const data *a = aa;
    const data *b = bb;
    return strcmp(a->type, b->type);
}

int compare_furnish(const void *aa, const void *bb) {
    const data *a = aa;
    const data *b = bb;
    return strcmp(a->furnish, b->furnish);
}

#ifdef USE_QSORT

void data_sort(data arr[], int count, int cmp(const void *aa, const void *bb)) {
    // using qsort:
    qsort(arr, count, sizeof(*arr), cmp);
}

#else

//Generic Quick Sort for data type//
void data_swap(data *a, data *b) {
    if (a != b) {
        data temp = *a;
        *a = *b;
        *b = temp;
    }
}

int data_partition(data arr[], int low, int high, int cmp(const void *aa, const void *bb))
{
    data pivot = arr[high];
    int i = low;

    for (int j = low + 1; j < high; j++) {
        if (cmp(&arr[j], &pivot) < 0) {
            data_swap(&arr[i], &arr[j]);
            i++;
        }
    }
    data_swap(&arr[i], &arr[high]);
    return i;
}

void data_quick_sort(data arr[], int low, int high, int cmp(const void *aa, const void *bb))
{
    if (low < high) {
        int pi = data_partition(arr, low, high, cmp);
        data_quick_sort(arr, low, pi - 1, cmp);
        data_quick_sort(arr, pi + 1, high, cmp);
    }
}

void data_sort(data arr[], int count, int cmp(const void *aa, const void *bb))
{
    // using our quick sort implementation
    data_quick_sort(arr, 0, count - 1, cmp);
}

#endif

//Generic Search data
int data_search(data array[], int array_length,
                int cmp(const void *aa, const void *bb),
                const data *target, int *end)
{
    int low = 0;
    int high = array_length;

    while (low < high) {
        int middle = low + (high - low) / 2;
        if (cmp(&array[middle], target) < 0)
            low = middle + 1;
        else
            high = middle;
    }
    for (high = low; high < array_length && !cmp(&array[high], target); high++)
        continue;
    if (low < high) {
        *end = high;
        return low;
    } else {
        *end = -1;
        return -1;
    }
}

// end of search carpark
void data_print(const data *house, int idx, int end, int header) {
    if (header) {
        printf("%-25s %-15s %-10s %-5s %-10s %-8s %-10s %-10s\n",
               "Location", "City", "Price", "Rooms", "Bathroom",
               "Carpark", "Type", "Furnish");
    }
    while (idx < end) {
        printf("%-25s %-15s %-10d %-5d %-10d %-8d %-10s %-10s\n",
               house[idx].location, house[idx].city, house[idx].price,
               house[idx].room, house[idx].bathroom, house[idx].carpark,
               house[idx].type, house[idx].furnish);
        idx++;
    }
}

int data_read(data *house, int count, const char *fname, char *header, size_t header_len) {
    FILE *file = fopen(fname, "r");
    if (file == NULL) {
        fprintf(stderr, "Cannot open %s: %s\n", fname, strerror(errno));
        return -1;
    }
    if (!fgets(header, header_len, file))
        *header = '\0';

    char buffer[1000];
    int buffer_len = sizeof(buffer);
    int n = 0;
    while (n < count && fgets(buffer, buffer_len, file))
    {
        if (sscanf(buffer, "%99[^,],%99[^,],%d,%d,%d,%d,%99[^,],%99[^,\n]",
                   house[n].location, house[n].city, &house[n].price,
                   &house[n].room, &house[n].bathroom, &house[n].carpark,
                   house[n].type, house[n].furnish) == 8)
        {
            n++;
        }  else {
            printf("invalid record: %s\n", buffer);
        }
    }

    fclose(file);
    return n;
}

int data_write(const data *house, const char *fname, int start, int end) {
    FILE *file = fopen(fname, "w");
    if (file == NULL) {
        fprintf(stderr, "cannot open %s: %s\n", fname, strerror(errno));
        return -1;
    }
    fputs("Location 1,Location 2,Price,Rooms,Bathrooms,CarParks,Type,Furnish\n", file);
    for (int i = start; i < end; i++) {
        fprintf(file, "%s,%s,%d,%d,%d,%d,%s,%s\n",
                house[i].location, house[i].city, house[i].price,
                house[i].room, house[i].bathroom, house[i].carpark,
                house[i].type, house[i].furnish);
    }
    fclose(file);
    return end - start;
}

int main(void)
{
    data house[4000];
    char header[1000];
    int n = data_read(house, 4000, "data.csv", header, sizeof header);
    if (n < 0)
        return 1;

    //  for checking the output and file processed
    //  data_print(house, 0, n, 1);
    int done = 0;
    while (!done) {
        printf("\nWhat do you want to do?\n");
        printf("1.  Display data\n");
        printf("2.  Search data\n");
        printf("3.  Sort data\n");
        printf("4.  Export data\n");
        printf("5.  Exit\n");
        printf("Your choice: ");

        int input;
        int res = scanf("%d", &input);
        input_flush();
        if (res != 1)
            break;

        switch (input)
        {
        case 1:
        {
            printf("Number of rows: ");
            int rows;
            res = scanf("%d", &rows);
            input_flush();
            if (res != 1)
                break;
            printf("\n");
            if (rows > n)
                rows = n;
            data_print(house, 0, rows, 1);
            printf("\n");
            break;
        }
        case 2:
        {
            data target = { 0 };
            int (*cmp)(const void *aa, const void *bb) = NULL;

            switch (+get_data_field()) {
            case LOCATION:
                cmp = compare_location;
                printf("What location do you want to find? ");
                res = scanf("%99s", target.location);
                break;
            case CITY:
                cmp = compare_city;
                printf("What city do you want to find? ");
                res = scanf("%99s", target.city);
                break;
            case PRICE:
                cmp = compare_price;
                printf("What price do you want to find? ");
                res = scanf("%d", &target.price);
                break;
            case ROOM:
                cmp = compare_room;
                printf("How many rooms do you want to find? ");
                res = scanf("%d", &target.room);
                break;
            case BATHROOM:
                cmp = compare_bathroom;
                printf("How many bathrooms price do you want to find? ");
                res = scanf("%d", &target.bathroom);
                break;
            case CARPARK:
                cmp = compare_carpark;
                printf("How many carparks do you want to find? ");
                res = scanf("%d", &target.carpark);
                break;
            case TYPE:
                cmp = compare_type;
                printf("What location do you want to find? ");
                res = scanf("%99s", target.type);
                break;
            case FURNISH:
                cmp = compare_furnish;
                printf("What value of furnish do you want to find? ");
                res = scanf("%99s", target.furnish);
                break;
            default:
                break;
            }
            if (!cmp)
                break;

            input_flush();
            if (res != 1) {
                printf("input error\n");
                break;
            }
            data_sort(house, n, cmp);

            int end;
            int idx = data_search(house, n, cmp, &target, &end);
            if (idx >= 0) {
                printf("Data Found. Detail of data:\n");
                data_print(house, idx, end, 1);
                printf("\n");
            } else {
                printf("Data Not Found!\n");
            }
            break;
        }
        case 3:
        {
            int (*cmp)(const void *aa, const void *bb) = NULL;
            switch (+get_data_field()) {
            case LOCATION:
                cmp = compare_location;
                break;
            case CITY:
                cmp = compare_city;
                break;
            case PRICE:
                cmp = compare_price;
                break;
            case ROOM:
                cmp = compare_room;
                break;
            case BATHROOM:
                cmp = compare_bathroom;
                break;
            case CARPARK:
                cmp = compare_carpark;
                break;
            case TYPE:
                cmp = compare_type;
                break;
            case FURNISH:
                cmp = compare_furnish;
                break;
            default:
                break;
            }
            if (!cmp)
                break;

            data_sort(house, n, cmp);
            break;
        }
        case 4:
        {
            char fname[100];
            printf("Name of output file: ");
            res = scanf("%99[^\n]", fname);
            input_flush();
            if (res != 1)
                break;
            printf("Number of rows (0 for all): ");
            int rows;
            res = scanf("%d", &rows);
            input_flush();
            if (res != 1)
                break;
            if (rows == 0 || rows > n)
                rows = n;
            int nwritten = data_write(house, fname, 0, rows);
            if (nwritten >= 0) {
                printf("%d records written to %s\n", nwritten, fname);
            }
            break;
        }
        case 5:
        default:
            done = 1;
            break;
        }
    }
    printf("\n");

    return 0;
}

相关问题