简体   繁体   中英

How to read data from text file and sort a specific column in ascending order using the array method in C language?

I am trying to read from a text file called "tel.txt" and sort the employees records in department-wise ascending order using array method, but I couldn't identify the bug in my codes and think the error comes from line between tag /* problematic code - */

tel.txt:

TP1|James|1231|sales|
TP2|chong|5324|admin|
TP3|Jack|1250|Finance|

The output I want on the screen (sorted by department):

TP2|chong|5324|admin|
TP3|Jack|1250|Finance|
TP1|James|1231|sales|
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
    
struct employee{
    char id[10], name[40], department[15];
        int telephone;
}; 

int main() {
    struct employee dep_sort[20];
    int count_line = 0, row, col;
    char temp_store[20], c;

    ptr = fopen("tel.txt", "r");
    if (ptr == NULL)
    {
        printf("error file");
        exit(1);
    }
    while ((c = fgetc(ptr)) != EOF)
    {
        if (c == '\n')
        {
            count_line++;
        }
    }
    /* problematic code -start*/
    while (c != EOF){
        row = 0;
        fscanf(ptr, "%[^|]|%[^|]|%d|%[^|]|\n", &dep_sort[row].id, &dep_sort[row].name, &dep_sort[row].telephone, &dep_sort[row].department);
        row++;
    }
    /* problematic code -end */ 
    
    for (row = 1; row <= count_line; row++) {
        for (col = 0; col <= count_line - row; col++) {
            if (strcmp(dep_sort[col].department, dep_sort[col + 1].department) > 0) {
                strcpy(temp_store, dep_sort[col].department);
                strcpy(dep_sort[col].department, dep_sort[col + 1].department);
                strcpy(dep_sort[col + 1].department, temp_store);
            }
        }
    }

    for (row = 0; row <= count_line; row++) {
        printf("\nID: %s\nName: %s\nTelephone: %d\nDepartment: %s\n", dep_sort[row].id, dep_sort[row].name, dep_sort[row].telephone, dep_sort[row].department);;
    }
    fclose(ptr);
}

I would separate the problem in three distinct steps: reading the file, sorting, displaying.

Note that, while sorting, you can directly swap the structures; no need to swap each individual field.

You can also avoid writing the sorting algorithm if you use the standard qsort() function and you provide your comparison criterion.

/**
  gcc -std=c99 -o prog_c prog_c.c \
      -pedantic -Wall -Wextra -Wconversion \
      -Wwrite-strings -Wold-style-definition -Wvla \
      -g -O0 -UNDEBUG -fsanitize=address,undefined
**/

#if defined _MSC_VER
# define _CRT_SECURE_NO_WARNINGS
# define strcasecmp _stricmp
#else
# undef __STRICT_ANSI__ // strcasecmp
#endif
#include <string.h>

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

typedef struct
{
  char id[10], name[40], department[15];
  int telephone;
} Employee; 

int // employee count
read_employees(const char *file_name,
               Employee *employees,
               int capacity)
{
  FILE *input=fopen(file_name, "r");
  if(input==NULL)
  {
    perror("open file for reading");
    exit(1);
  }
  int count=0;
  char line[100];
  while((count<capacity)&&fgets(line, 100, input))
  {
    Employee *e=employees+count;
    int r=sscanf(line, "%[^|]|%[^|]|%d|%[^|]|",
                 e->id, e->name, &e->telephone, e->department);
    if(r==4) // 4 fields successfully extracted
    {
      ++count;
    }
  }
  fclose(input);
  return count;
}

void
sort_employees_by_department(Employee *employees,
                             int count)
{
  for(int i=0; i<count; ++i)
  {
    Employee *ei=employees+i;
    for(int j=i+1; j<count; ++j)
    {
      Employee *ej=employees+j;
      if(strcasecmp(ei->department, ej->department)>0)
      {
        Employee tmp=*ei;
        *ei=*ej;
        *ej=tmp;
      }
    }
  }
}

int
compare_employees_by_department(const void *lhs,
                                const void *rhs)
{
  const Employee *le=lhs;
  const Employee *re=rhs;
  return strcasecmp(le->department, re->department);
}

void
show_employees(const Employee *employees,
               int count)
{
  for(int i=0; i<count; ++i)
  {
    const Employee *e=employees+i;
    printf("ID: %s|Name: %s|Telephone: %d|Department: %s\n",
           e->id, e->name, e->telephone, e->department);
  }
}

int
main(void)
{
  Employee employees[20];
  int count=read_employees("tel.txt", employees, 20);
#if 1
  sort_employees_by_department(employees, count);
#else
  qsort(employees, (size_t)count, sizeof(Employee),
        compare_employees_by_department);
#endif
  show_employees(employees, count);
  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM