Home > OS >  Scanning a newline using fgets from a .txt file in C
Scanning a newline using fgets from a .txt file in C

Time:11-10

I have a text file (fruits.txt), which looks something like this:

apple chloe
banana ben james
grape chloe james
kiwi ben chloe james
orange ben james
pear ben

I want to order all of this text into something like

ben: banana kiwi pear
chloe: apple grape kiwi orange
james: banana grape kiwi orange

in a C program.

What I was originally thinking was using fgets(), sscanf() or fscanf(), but I ran into quite a few problems because not all of the lines in fruits.txt has the same amount of words, which resulted in making a fixed scanning format

(such as fscanf("%s %s %s", name, fruit1, fruit2))

impossible, thus requiring me to scan a newline from fruits.txt. However, I cannot think of a way to code this because it seemed like scanning in a string with %s does not include a newline.

Can someone help me out through this problem? Any help will be appreciated.

CodePudding user response:

As an exercise for myself I implemented what you're looking for.

You should adjust the array sizes as required. It just prints the output to stdout but of course you can change this to write to file that's what you need.

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

#define MAX_PEOPLE    10
#define MAX_FRUIT     10
#define MAX_LINE_LEN  120
#define MAX_TOKEN_LEN 10
 
// Driver code
int main()
{
    FILE* fp;
    char line[MAX_LINE_LEN];
    char person[MAX_PEOPLE][MAX_TOKEN_LEN] = {};
    char fruit[MAX_FRUIT][MAX_TOKEN_LEN] = {};
    int personFruit[MAX_PEOPLE][MAX_FRUIT] = {0};
    int numFruit = 0;
    int numPeople = 0;
    
    // Open file in reading mode
    fp = fopen("fruits.txt", "r");
    if (NULL == fp) {
        printf("file can't be opened \n");
        return 0;
    }
 
    // Process input file line by line
    while (fgets(line, MAX_LINE_LEN, fp) != NULL) {

            int nToken = 0, nFruitIndex = 0;
            char* token = strtok(line, " ");
            while (token != NULL) {

                // Trim trailing line-feed if present
                if (token[strlen(token) - 1] == '\n')
                    token[strlen(token) - 1] = '\0';

                // Add first token to fruit array
                if (nToken   == 0) {
                    nFruitIndex = numFruit;
                    strcpy(fruit[numFruit  ], token);
                }
                else {
                    // Process people tokens on line 
                    // Is this a new person or someone already encountered?
                    int nPersonIndex = 0, bFoundPerson = 0;
                    for (int i = 0; i < numPeople; i  ) {
                        if (strcmp(token, person[i]) == 0) {
                            nPersonIndex = i;
                            bFoundPerson = 1;
                            break;
                        }
                    }
                    if (!bFoundPerson) {
                        nPersonIndex = numPeople;
                        strcpy(person[numPeople  ], token);
                    }
                    personFruit[nPersonIndex][nFruitIndex]  ;
                }

                // Get next token
                token = strtok(NULL,  " ");
            }
    }

    // Print output - list fruit each person has
    for (int i = 0; i < numPeople; i  ) {
        printf("%s:", person[i]);
        for (int j = 0; j < numFruit; j  )
            if (personFruit[i][j] > 0)
                printf(" %s", fruit[j]);
        printf("\n");
    }

    // Close file
    fclose(fp);
    return 0;
}
  • Related