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;
}