Search code examples
carrayssortingc-strings

Read text file, break each line into separate arrays and sort in C


I am trying to write a program that reads a text file and breaks each line into separate arrays so they can be sorted by date and name. I am still having trouble getting the 'sort by date' function to work/display properly, which is why I haven't attempted the sort by name function yet.

I seem to be able to scan in the date and name arrays fine, but I think I need to modify the way I scan in the last array 'dates' because I need to separate them with a space after a comma. Problem is that I am not sure how to scan them in as a string seeing as they would have spaces between them and some names have different numbers of states. (I removed the spaces between the states in the text file at this point, but the text file needs to have them back in probably?)

My code so far...

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

#define MAX 30

void sortByDate( int year[], char *name[], char *states[], int count);
void sortByName(int year[], char name[], char states[], int count);

int main()
{
     int year[MAX]; 
     int i, a;
     int count = 0;
     int choice;
     char *name[MAX],
          *states[MAX];
     char b[MAX], c[MAX];

     FILE *inp = fopen("hurricanes.txt","r");               /* defining file input    */

     for(i=0;i<MAX;i++)
     {
         if( feof(inp) )
        {
            break;
        } 
        fscanf(inp, "%d", &a);
        fscanf(inp, "%s", &b);
        fscanf(inp, "%s", &c);
        year[i]=a;
        strcpy(&name[i],b);
        strcpy(&states[i],c);
        ++count; 

        printf("%d %s %s\n", year[i], &name[i], &states[i]);
     }

     printf("Press 0 to sort by date or 1 to sort by name: ");
     scanf("%d", &choice);  
     if (choice == 0)
     {
         sortByDate(year, name, states, count); 
     }
     else if ( choice == 1)
     {
          //sortByName(year, name, states, count); 
     }

     getch();
     return 0;
}

void sortByDate( int year[], char *name[], char *states[], int count )
{
     int d = 0;
     int c = 0;

     int yearTmp;
     char nameTmp[MAX], statesTmp[MAX];
     int order[count];
     int tmp = 0;

     FILE *outp = fopen("report.txt","w");                 /* defining file output   */

     for (c = 0; c < count; ++c)
     {
         order[c] = c; 
     } 

     for (c = 0 ; c < ( count - 1 ); c++)
     {
          for (d = 0 ; d < count - c - 1; d++)
          {
               if (year[d] > year[d+1])
               {
                    yearTmp = year[d];
                    year[d] = year[d+1]; 
                    year[d+1] = yearTmp; 

                    tmp = order[d];
                    order[d] = order[d+1];
                    order[d+1] = tmp;   
              }
          }
     }

     for (c = 0; c < count; ++c)
     {
          printf("%d %-10s %s\n",  year[c], &name[order[c]], &states[order[c]]); 
     } 
}

//void sortByName(int year[], char name[], char states[], int count)
//{
//} 

The hurricanes.txt file....(again, I have removed the spaces between states but I think they need to be put back in and scanned differently?)

1960 Donna FL,NC
1969 Camille MS
1972 Agnes FL
1983 Alicia TX
1989 Hugo SC,NC
2005 Katrina FL,LA,MS
2005 Rita TX,LA
2005 Wilma FL
2008 Ike TX
2009 Ida MS
2011 Irene NC,NJ,MA,VT
2012 Isaac LA
1992 Andrew FL,LA
1995 Opal FL,AL
1999 Floyd NC
2003 Isabel NC,VA
2004 Charley FL,SC,NC
2004 Frances FL
2004 Ivan AL
2004 Jeanne FL

Ok, So I made some changes from the suggestions posted here and they worked out great!


Solution

  • If your EOL character is a \n, you could use this:

    fscanf(inp, "%d %s %29[^\n]", &a, b, c);
    

    where 29 is MAX - 1. Replace \n with your EOL character(s).

    Please note that you don't need to pass &b, &c to fscanf since your compiler will convert b and c to &b[0] and &c[0]. Also, on printf you are passing &name[i], wich is a char ** when your compiler is expecting a char *. You need to change &name[i] to name[i]. The same for &states[i].