Reading a partition delimiter using getchar ()

I am trying to read a text file using input redirection ./program < file.txt, and the file I created looks like this:

Country\tSport\tGender\tMedal\n
America\tCycling\tMens\tGold\n
New Zealand\tSwimming\tWomens\tSilver\n
India\tBadminton\tMens\tbronze\n

That only reads some random data, in accordance with the first line with 4 columns, headed Country, Sport, Genderand Medal.

I also added \tand \nto make the file more readable, but in fact it has tabs and newline characters.

I am trying to read every line of this file and store them in an array of lines, which I declared as:

char *records[ROWS][COLUMNS];

I would like the array of strings to recordslook something like this:

{{"Country", "Sport", "Gender", "Medal"}, {"America", "Cycling", "Mens", "Gold"}, 
{"New Zealand", "Swimming", "Womens", "Silver"}, {"India", "Badminton", "Mens", "Bronze"}}

So far, I just used scanfto read lines, for example:

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

#define ROWS 1000
#define COLS 30
#define MAX_CH 50

int
main(int argc, char *argv[]) {
    char *records[ROWS][COLS];

    char country[MAX_CH];
    char sport[MAX_CH];
    char gender[MAX_CH];
    char medal[MAX_CH];

    while (scanf("%s\t%s\t%s\t%s\n", country, sport, gender, medal) == 4) {
        printf("%s %s %s %s\n", country, sport, gender, medal);
    }

    return 0;
}

, , New Zealand , scanf wil . scanf , 4 .

getchar() ? , getchar .

+4
4

getchar .

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

#define ROWS 1000
#define COLS 30
#define MAX_CH 50

void print_array(char str[][COLS][MAX_CH], int nrows, int ncols, int col[], int reorder);
void sort_array(char str[][COLS][MAX_CH], int nrows, int ncols, int col[]);


int main( int argc, char *argv[])
{
    char records[ROWS][COLS][MAX_CH] = { { { '\0'}}};//set each element
    char item[MAX_CH] = { '\0'};//buffer for each item
    //char yn[40];
    int row = 0;
    int col = 0;
    int usedcol = 0;
    int sortby[COLS] = { 0};
    int ch = 0;
    int each = 0;
    int loop = 0;
    int result = 0;

    if ( argc < 2 || argc > COLS + 1) {
        fprintf ( stderr, "syntax is\n%s column0 [column1]...[column%d] < inputfile\n", argv[0], COLS - 1);
        exit(EXIT_FAILURE);
    }

    for ( each = 1; each <= COLS + 1; each++) {// +1 to get to extra element
        sortby[each - 1] = -1;//extra element will be -1
        if ( each < argc) {
            if ( ( result = sscanf ( argv[each], "%d", &sortby[each - 1])) != 1 || sortby[each - 1] < 0 || sortby[each - 1] >= COLS) {
                fprintf ( stderr, "syntax is\n%s column0 [column1]...[column%d] < inputfile\n", argv[0], COLS - 1);
                fprintf ( stderr, "column%d must be 0 to %d\n", each - 1, COLS - 1);
                exit(EXIT_FAILURE);
            }
        }
    }

    for ( each = 0; each < argc - 1; each++) {
        for ( loop = 0; loop < argc - 1; loop++) {
            if ( loop != each && sortby[each] == sortby[loop]) {
                fprintf ( stderr, "found duplicate columns in args\n");
                exit(EXIT_FAILURE);
            }
        }
    }
    //printf ( "\n");

    if ( isatty ( fileno ( stdin))) {
        printf ( "expected that a file would be redirected to this program\n");
        printf ( "syntax is\n%s column0 [column1]...[column%d] < inputfile\n", argv[0], COLS - 1);
        //printf ( "enter y to continue WITHOUT the redirected file?\n");
        //if ( ( fgets ( yn, sizeof ( yn), stdin))) {
            //if ( strcmp ( yn, "y\n") != 0) {
                exit(EXIT_FAILURE);
            //}
        //}
    }

    row = 0;
    col = 0;
    each = 0;
    while ( ( ch = getchar ( )) != EOF) {//read each character
        if ( ch == '\r') {//skip carriage return
            continue;
        }
        if ( ch == '\t') {
            strcpy ( records[row][col], item);
            each = 0;//back to first character
            col++;//next column
            if ( col >= COLS) {
                col = 0;
                row++;
                if ( row >= ROWS) {
                    fprintf ( stderr, "too many rows\n");
                    break;
                }
            }
            continue;
        }
        if ( ch == '\n') {
            strcpy ( records[row][col], item);
            col++;
            if ( col > usedcol) {
                usedcol = col;
            }
            col = 0;//back to first column
            each = 0;//back to first character
            row++;//next row
            if ( row >= ROWS) {
                fprintf ( stderr, "too many rows\n");
                break;
            }
            continue;
        }
        item[each] = ch;
        each++;//next character
        item[each] = '\0';//terminate with '\0'
        if ( each >= MAX_CH - 1) {
            fprintf ( stderr, "too many characters in item\n");
            each = 0;
            col++;
            if ( col >= COLS) {
                col = 0;
                row++;
                if ( row >= ROWS) {
                    fprintf ( stderr, "too many rows\n");
                    break;
                }
            }
            continue;
        }
    }

    print_array ( records, row, usedcol, sortby, 0);

    sort_array ( records, row, usedcol, sortby);

    print_array ( records, row, usedcol, sortby, 1);

    return 0;
}

void print_array(char str[][COLS][MAX_CH], int nrows, int ncols, int col[], int reorder) {
    int i, j;
    int order[COLS] = { 0};

    for ( i = 0; i < COLS; i++) {
        if ( reorder) {
            order[i] = col[i];
        }
        else {
            order[i] = i;
        }
    }

    if ( reorder) {
        for ( i = 0; i < COLS; i++) {
            for ( j = 0; j < COLS; j++) {
                if ( order[j] == i) {
                    break;
                }
                if ( order[j] == -1) {
                    order[j] = i;
                    break;
                }
            }
        }
    }

    for (i = 0; i < nrows; i++) {
        for (j = 0; j < ncols; j++) {
            printf("%-12s ", str[i][order[j]]);
        }
        printf("\n");
    }
    printf("\n");
}

void sort_array(char str[][COLS][MAX_CH], int nrows, int ncols, int col[]) {
    int i = 0, j = 0, swap = 0, each = 0;
    char temp[MAX_CH] = { '\0'};

    do {
        swap = 0;
        for ( i = 1; i < nrows - 1; i++) {//iterate through rows. i=1 skip first row

            for ( each = 0; col[each] != -1; each++) {//col[] has last element of -1

                if ( strcmp( str[i][col[each]], str[i + 1][col[each]]) < 0) {
                    break;
                }
                if ( strcmp( str[i][col[each]], str[i + 1][col[each]]) == 0) {
                    continue;
                }
                for ( j = 0; j < ncols; j++) {//iterate through cols and swap rows
                    strcpy ( temp, str[i][j]);
                    strcpy ( str[i][j], str[i + 1][j]);
                    strcpy ( str[i + 1][j], temp);
                }
                swap = 1;
                break;
            }
        }
    } while ( swap);//loop until no swaps
}
+1

getChar():

while (char = getChar()) is not 'EOF': // EOF = End of file
    if char is not '\t' and char is not '\n'
        save into current string
    else if char is '\t'
        terminate current string
        increment column index
    else if char is '\n'
        terminate current string
        increment row index

Edit:

getChar() , , .

, , , , ( ).

strcat() , char char* char[] (String) :

char string[] = "MINE"; // string[0] -> 'M'
string[0] = 'N'; // string -> "NINE"

// with dynamic memory allocation
char *string = (char*) malloc(5*sizeof(char));
string[0] = 'N'; // string -> "N"
+2

:

  • records[][]
  • : argc
  • : argv
  • puts all the input in the first entries in the arrays: country [], sport [], gender [], medal [] IE all other entries are not used
  • does not handle "columns" containing spaces
  • contains a header file whose contents are not used: string.h

The following code fully compiles and performs the required function:

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

#define ROWS 1000
//#define COLS 30
#define MAX_CH 49

struct record
{
    char country[ MAX_CH+1 ];
    char sport  [ MAX_CH+1 ];
    char gender [ MAX_CH+1 ];
    char medal  [ MAX_CH+1 ];
};

int main( void ) 
{
    struct record records[ROWS];

    for( size_t i=0; i< ROWS; i++)
    {
        if( scanf(" %" MAX_CH "[^\t] %" MAX_CH "[^\t] %" MAX_CH "[^\t] %" MAX_CH "[^\n]", 
                records[i].country, 
                records[i].sport, 
                records[i].gender, 
                records[i].medal) == 4) 
        {
            printf("%s %s %s %s\n", 
                    records[i].country, 
                    records[i].sport, 
                    records[i].gender, 
                    records[i].medal);
        }

        else
        {
            break;
        }
    }

    return 0;
} // end function: main
+1
source

Source: https://habr.com/ru/post/1653308/


All Articles