-2

Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Read
{
    char str1[64];
    int year;
    char type[64];
    char str2[64];
} read;

void remove_new_line(char*);

int main(int argc, char *argv[])
{
    FILE *fp = NULL;
    char line[256];
    char* token;
    int i = 0;
    char input[50];
    char command[50];
    char val1[30];
    char val2[30];
    read info[8];

    if (argc <= 1)
    {
        printf("The file does not exist\n");
        return 0;
    }
    fp = fopen(argv[1], "r");
    if (fp == NULL)
    {
        printf("No File Exists\n");
        return 0;
    }
    while (fgets(line, sizeof(line), fp))
    {
        remove_new_line(line);
        token = strtok(line, ",");
        strcpy(info[i].str1, token);
        token = strtok(NULL, ",");
        info[i].year = atoi(token);
        token = strtok(NULL, ",");
        strcpy(info[i].type, token);
        token = strtok(NULL, ",");
        strcpy(info[i++].str2, token);
    }

    while (1)
    {
        scanf(" %49[^\n]s", input);
        fflush(stdin);

        command[0] = 0;
        val1[0] = 0;
        val2[0] = 0;

        sscanf(input, "%s, %s, %s", command, val1, val2);

        if (strcmp(command, "SORT") == 0)
        {
            printf("%s | %d | %s | %s\n", info[0].str1, info[0].year, info[0].type, info[0].str2);
        }
        else if (strcmp(command, "QUIT") == 0)
        {
            exit(0);
        }
        break;
    }
    return 0;
}
void remove_new_line(char* str)
{
    char* p;
    if (p = strchr(str, '\n'))
    {
        *p = '\0';
    }
}

And the text file is:

Dive,2011,Electronic,Tycho
Portraits,2015,Electronic,Maribou State
Mer De Noms,2000,Hard Rock,A Perfect Circle
Awake,2014,Electronic,Tycho
Epoch,2016,Electronic,Tycho
Farewell,2016,Chamber,Cicada
The Beatles,1968,Rock,The Beatles
Sines,2014,Post-Metal,Jakob

What I want to do is to make a variable named "column" and store info[0~3].str1 in column[0], and info[0~3].year in column[1] and so on. This is for the later work, which is to select column that I want to sort in an ascending order (or descending order) through calling strcmp function.

Jens
  • 69,818
  • 15
  • 125
  • 179
  • 1
    [`fflush(stdin);` is undefined behaviour, don't do it](http://stackoverflow.com/a/38325926/2173917). – Sourav Ghosh May 06 '17 at 07:04
  • If the `input` as your command is comma-delimited, `%s` of `sscanf`--> `%[^,],` – BLUEPIXY May 06 '17 at 07:28
  • How should I store the info[i].str1, info[i].year and so on in the col..? Should I use 3D malloc? – Yoo SungKyung May 06 '17 at 07:33
  • I think that it is not necessary to store them in another variable. – BLUEPIXY May 06 '17 at 07:42
  • how should I approch to what I am expecting to ahcieve?... – Yoo SungKyung May 06 '17 at 07:45
  • Rather than preparing a column in one comparison function for sorting, prepare a comparison function as many as the number of columns. – BLUEPIXY May 06 '17 at 07:50
  • 2
    @SouravGhosh: the Windows documentation [defines the behaviour of `fflush()`](https://msdn.microsoft.com/en-us/library/9yky46tz.aspx) used with *input streams* as an extension to the standard. At least on that platform it isn't UB. – pmg May 06 '17 at 13:04
  • Your current code that reads (seems to read) the data into a structure is appropriate. If you need to sort on different columns, you can simple use the standard C library `qsort()` function with different comparator functions, each of which sorts on a different column. Writing those is not hard. – Jonathan Leffler May 06 '17 at 14:11
  • This link has a nuanced description of the limitations and possibilities of [Using `fflush(stdin)`](http://stackoverflow.com/questions/2979209/using-fflushstdin). – Jonathan Leffler May 06 '17 at 20:09

1 Answers1

0

As I noted in a comment, your current code does an OK job of reading the data into the structure. It's then not hard to write the functions that can sort the structure on any of the fields — rather than needing to use the hand-waving description of somehow creating a column to be sorted.

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

typedef struct Read
{
    char str1[64];
    int year;
    char type[64];
    char str2[64];
} read;

static void remove_new_line(char*);

static void print_info(const char *tag, int n, read *info)
{
    printf("%s:\n", tag);
    for (int j = 0; j < n; j++)
        printf("%s | %d | %s | %s\n", info[j].str1, info[j].year, info[j].type, info[j].str2);
}

static int cmp_str1(const void *v1, const void *v2)
{
    const read *r1 = v1;
    const read *r2 = v2;
    return strcmp(r1->str1, r2->str1);
}

static int cmp_type(const void *v1, const void *v2)
{
    const read *r1 = v1;
    const read *r2 = v2;
    return strcmp(r1->type, r2->type);
}

static int cmp_str2(const void *v1, const void *v2)
{
    const read *r1 = v1;
    const read *r2 = v2;
    return strcmp(r1->str2, r2->str2);
}

static int cmp_year(const void *v1, const void *v2)
{
    const read *r1 = v1;
    const read *r2 = v2;
    return (r1->year > r2->year) - (r1->year < r2->year);
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s file\n", argv[0]);
        return 1;
    }
    FILE *fp = fopen(argv[1], "r");
    if (fp == NULL)
    {
        fprintf(stderr, "Unable to open file %s for reading\n", argv[1]);
        return 1;
    }

    read info[8];
    char line[256];
    int i = 0;
    while (fgets(line, sizeof(line), fp) != 0 && i < 8)
    {
        remove_new_line(line);
        //printf("In: %s\n", line);
        char *token = strtok(line, ",");
        //printf("T1: [%s]\n", token);
        strcpy(info[i].str1, token);
        token = strtok(NULL, ",");
        //printf("T2: [%s]\n", token);
        info[i].year = atoi(token);
        token = strtok(NULL, ",");
        //printf("T3: [%s]\n", token);
        strcpy(info[i].type, token);
        token = strtok(NULL, ",");
        //printf("T4: [%s]\n", token);
        strcpy(info[i++].str2, token);
    }
    fclose(fp);

    print_info("\nBefore sorting", i, info);
    qsort(info, i, sizeof(info[0]), cmp_str1);
    print_info("\nSort on str1", i, info);
    qsort(info, i, sizeof(info[0]), cmp_year);
    print_info("\nSort on year", i, info);
    qsort(info, i, sizeof(info[0]), cmp_type);
    print_info("\nSort on type", i, info);
    qsort(info, i, sizeof(info[0]), cmp_str2);
    print_info("\nSort on str2", i, info);

    return 0;
}

static void remove_new_line(char* str)
{
    char* p;
    if ((p = strchr(str, '\n')) != 0)
    {
        *p = '\0';
    }
}

Example run:

Before sorting:
Dive | 2011 | Electronic | Tycho
Portraits | 2015 | Electronic | Maribou State
Mer De Noms | 2000 | Hard Rock | A Perfect Circle
Awake | 2014 | Electronic | Tycho
Epoch | 2016 | Electronic | Tycho
Farewell | 2016 | Chamber | Cicada
The Beatles | 1968 | Rock | The Beatles
Sines | 2014 | Post-Metal | Jakob

Sort on str1:
Awake | 2014 | Electronic | Tycho
Dive | 2011 | Electronic | Tycho
Epoch | 2016 | Electronic | Tycho
Farewell | 2016 | Chamber | Cicada
Mer De Noms | 2000 | Hard Rock | A Perfect Circle
Portraits | 2015 | Electronic | Maribou State
Sines | 2014 | Post-Metal | Jakob
The Beatles | 1968 | Rock | The Beatles

Sort on year:
The Beatles | 1968 | Rock | The Beatles
Mer De Noms | 2000 | Hard Rock | A Perfect Circle
Dive | 2011 | Electronic | Tycho
Awake | 2014 | Electronic | Tycho
Sines | 2014 | Post-Metal | Jakob
Portraits | 2015 | Electronic | Maribou State
Epoch | 2016 | Electronic | Tycho
Farewell | 2016 | Chamber | Cicada

Sort on type:
Farewell | 2016 | Chamber | Cicada
Epoch | 2016 | Electronic | Tycho
Dive | 2011 | Electronic | Tycho
Awake | 2014 | Electronic | Tycho
Portraits | 2015 | Electronic | Maribou State
Mer De Noms | 2000 | Hard Rock | A Perfect Circle
Sines | 2014 | Post-Metal | Jakob
The Beatles | 1968 | Rock | The Beatles

Sort on str2:
Mer De Noms | 2000 | Hard Rock | A Perfect Circle
Farewell | 2016 | Chamber | Cicada
Sines | 2014 | Post-Metal | Jakob
Portraits | 2015 | Electronic | Maribou State
The Beatles | 1968 | Rock | The Beatles
Awake | 2014 | Electronic | Tycho
Dive | 2011 | Electronic | Tycho
Epoch | 2016 | Electronic | Tycho
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278