-2

I'm very noob in C, and also we are not allowed to use ftell() or something similar. I can't print out the contents of my file as it is asked from me.This is eventually task in which I should've created functions that reads contents of file and store it in array then returns number of items in file, and in main() I had to print out using readStations() function. In main() also there should've been railwayLine[100] array of type station.

File has text as follows:

1. 0.0 London-Kings-Cross*
2. 3.9 Finsbury-Park*
...

First of all, I created typedef struct called station with properties km and name which are the distance and name of stations. I've tried to create function readStations(char filename[20], station line[])

My attempt is as follows:

 #include <stdio.h>

 typedef struct {
   char name[30];
   double km;
 } station;

 int readStations(char filename[20], station line[]){

   FILE* openedFile;
   openedFile = fopen(filename, "r");

   if(openedFile == NULL){ 
     printf("Some problem occured with opening of file");
     return 1;
   }

   station stations;

   int count = 0;
   for (; !feof(openedFile); count++){
     fscanf(openedFile, "%lf %s", &stations.km, stations.name);
   }

   int numberOfStations = count;

   return count;
  }


  int main(){

    station railwayLine[100];
    printf("");
  }

Actually, it returns me the number of items of .txt file but in main I don't know how to print out all items as they look in .txt file.

mrflash818
  • 930
  • 13
  • 24
  • Use `ftell` to get the file size, and then use `fread` to get the entire amount of data into a buffer (array of characters) which you can then print. – goodvibration Oct 18 '19 at 11:13
  • @goodvibration we are not allowed to use ftell() or any other similar stuff =( – honeychickenrice Oct 18 '19 at 11:15
  • 1
    @MarkDark _"we are not allowed to use ftell()...."_, that information belongs into the question. – Jabberwocky Oct 18 '19 at 11:17
  • You'd have to call `readStations()`. You probably need a dynamically allocated array of stations (you can `malloc()` an initial array, and then `realloc()` each time you need more space (double the number of allocated stations each time you add more space). That will be tracked via a pointer — which could perhaps be global, or could be returned instead of the number of stations read, or you could create another structure type containing a count of the number of stations read, a count of the number of structures allocated, and a pointer to the structures. This would be how I'd do it. – Jonathan Leffler Oct 18 '19 at 11:22
  • Ouch! Such limitations make life difficult — and it is crucial that such restrictions are documented so those attempting to help can do so usefully. Of course, you're using at least 3 pointers in your `readStations()` function — both parameters are 'really' pointers, and there's a `FILE *` too. Your `main()` function needs to be a little less minimal, I think. It should show the call to `readStations()` (though it isn't too hard to guess what it looks like — but guessing shouldn't be necessary and many a problem has been solved by looking at the calling code rather than the called code). – Jonathan Leffler Oct 18 '19 at 11:28
  • Your code in the function needs to write to the `line` array that is passed into the function — at the moment, you ignore that parameter. You can return the count of stations. A redesigned interface would pass the maximum number of stations in the array defined in `main()` so you can avoid a [stack overflow](https://stackoverflow.com/) problem. And you can write a function to print the values in an array of `station` entries. – Jonathan Leffler Oct 18 '19 at 11:30
  • 1
    Also, note that [`while (!feof(file))` is always wrong](https://stackoverflow.com/questions/5431941/) even when the condition is in a `for` loop instead of a `while` loop. – Jonathan Leffler Oct 18 '19 at 11:34
  • Is it required to store everything before printing? If yes, that is certainly not a right way to print content of files. The best is to print each sample content as it is read. Leffler's suggestions are the best if you can't do that. – Jean-Baptiste Yunès Oct 18 '19 at 12:37
  • @JonathanLeffler Is `do ... while(!feof(file))` OK? – S.S. Anne Oct 18 '19 at 17:14
  • Not really. You also need to test the read operation and respond to it reporting EOF. So, by the time you reach the end `while` test, you should already be aware that you’ve reached EOF, so the test is superfluous. – Jonathan Leffler Oct 18 '19 at 17:17

1 Answers1

1

This seems to meet your concerns. Note that the readStations() function is now told how many stations it can store. It also closes the file that was opened. The printStations() function prints the data.

#include <stdio.h>

typedef struct
{
    char name[30];
    double km;
} station;

static int readStations(char filename[], int max_line, station line[])
{
    FILE *openedFile = fopen(filename, "r");

    if (openedFile == NULL)
    {
        fprintf(stderr, "Some problem occurred opening the file %s\n", filename);
        return 0;
    }

    int count;
    for (count = 0; count < max_line; count++)
    {
        if (fscanf(openedFile, "%lf %s", &line[count].km, line[count].name) != 2)
            break;
    }

    fclose(openedFile);
    return count;
}

static void printStations(int num_stations, station line[])
{
    for (int i = 0; i < num_stations; i++)
        printf("%2d. %6.2f km - %s\n", i, line[i].km, line[i].name);
}

int main(void)
{
    enum { MAX_STATIONS = 100 };
    station railwayLine[MAX_STATIONS];
    int num_stations = readStations("stations.txt", MAX_STATIONS, railwayLine);
    printStations(num_stations, railwayLine);
}

Given input data (file stations.txt):

0.0 London-Kings-Cross*
3.9 Finsbury-Park*

The output is:

 0.   0.00 km - London-Kings-Cross*
 1.   3.90 km - Finsbury-Park*
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278