nlowe
nlowe

Reputation: 37

How to read values from a .txt file into a program in C

I'm having trouble reading values from a txt file into my program. I'm given values as coordinates (x,y) followed by 2 spaces. It's given that the max number of points is 100, so how can I read the input so that my program will read only the given amount of values per line? My program so far is aimed at calculating the distance between two points and using the sum to find the perimeter.

3 12867 1.0 2.0  1.0 5.0  4.0 5.0  
5 15643 1.0 2.0  4.0 5.0  7.8 3.5  5.0 0.4  1.0 0.4

So far I've all I can come up with is:

scanf("%f %f %f %f %f %f", &x1, &y1, &x2, &y2, &x3, &y3);

This is my program so far as well.

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

#define MAX_PTS 100
#define MAX_POLYS 100
#define END_INPUT 0

struct Point {
    double x, y;
};

double getDistance(struct Point a, struct Point b) {
    double distance;
    distance = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) *(a.y-b.y));
    return distance;
}

int main(int argc, char *argv[]) {
    int npoints, poly_id;
    struct Point a, b;

    if(scanf("%d %d", &npoints, &poly_id)) {
        scanf("%lf %lf", &a.x, &a.y);
        scanf("%lf %lf", &b.x, &b.y);
    } else { printf("\nUnable to read input.\n");
      exit(EXIT_FAILURE);
    }

    printf("\nStage 1\n=======\n");
    printf("First polygon is %d\n", poly_id);
    printf("   x_val   y_val\n    %1.1f     %1.1f\n    %1.1f     %1.1f\n",
    a.x, a.y, b.x, b.y);
    printf("perimeter = %2.2lf m\n", getDistance(a, b));


    return 0;
}

Output being:

First polygon is 12867
   x_val   y_val
    1.0     2.0
    1.0     5.0
perimeter = 3.00 m

Edit: I must add that the txt file must be read using redirection, e.g. ./program < txt file

Upvotes: 0

Views: 1462

Answers (5)

Ashish Negi
Ashish Negi

Reputation: 5301

In programming, One uses loop when they want to do some work again and again.

Think that for calculating parimeter of a polygon, you need to calculate length of its edges. Your function getDistance can find length of an edge if it is given two adjacent points. So, you keep finding length of edges and adding them. Now think what is repetitive work. It is getDistance with new points. Therefore, look at for loop at the below code.

I have written some comments in code to illustrate the point.

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

#define MAX_PTS 100
#define MAX_POLYS 100
#define END_INPUT 0

struct Point {
    double x, y;
};

double getDistance(struct Point a, struct Point b) {
    double distance;
    distance = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) *(a.y-b.y));
    return distance;
}

int main(int argc, char *argv[]) {
    int npoints, poly_id;
    struct Point a, b;

    if(scanf("%d %d", &npoints, &poly_id)) {
        int iteration = 0;
        scanf("%lf %lf", &a.x, &a.y);
        struct Point initialPoint = a;
        double parimeter = 0;  // i start with 0 value of parimeter.     
        for (iteration = 1; iteration < npoints; ++iteration) {
            scanf("%lf %lf", &b.x, &b.y);  // take input for new-point.
            parimeter += getDistance(a, b); // add the parimeter.
       // for next iteration, new-point would be first-point in getDistance
            a = b; 
        }

        // now complete the polygon with last-edge joining the last-point
        // with initial-point.
        parimeter += getDistance(a, initialPoint);

        // print the information.
        printf("Polygon is %d\n", poly_id);
        printf("perimeter = %2.2lf m\n", parimeter); 
    } else { printf("\nUnable to read input.\n");
      exit(EXIT_FAILURE);
    }

    return 0;
}

See the code in action : Working Code.

Notice that i have given

input :

 3 12867 1.0 2.0 1.0 5.0 4.0 5.0

and output is :

Polygon is 12867
perimeter = 10.24 m

Now if you want to do this work for more polygons, hopefully you know what to do !!!

Upvotes: 0

samyak bhalerao
samyak bhalerao

Reputation: 307

Try following code snippet:

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

int main()
{
   char ch, file_name[25];
   FILE *fp;
   int count=0;
   int i,j;
   int cordinate[5][5];

   fp = fopen('a.txt',"r"); // read mode

   if( fp == NULL )
   {
      perror("Error while opening the file.\n");
      exit(EXIT_FAILURE);
   }

   while( ( ch = fgetc(fp) ) != EOF ){
      printf("%c",ch);
      for(i=0;i<5;i++)
      {
          for(j=0;j<5;j++){
               if(ch==' '){
          count++;
          cordinate[0][0]=
            }
         else{
          cordinate[i][j]=ch;
      }
      }
          }
      }
      printf('print content of file');
      for(i=0;i<5;i++)
      {
          for(j=0;j<5;j++){
              printf("cordinates:%d"+cordinate[i][j]);
          }
      }

   }

   fclose(fp);
   return 0;
}

Upvotes: 0

Sourav Ghosh
Sourav Ghosh

Reputation: 134336

Regarding your approach

To read data from a file, you need fscanf() function. Read the man page here.

Note: If you want to use fscanf() it is strongly recommended that you check the return value of the same to ensure proper input.

About the storing of values, you can use either of below approach

Alternative approach:

A better approach will be

  1. read the entire line using fgets().
  2. tokenize the input using strtok().
  3. convert the string to float using strtof()
  4. continue untill NULL from strtok(), indicates finished reading all the values in a line.
  5. continue untill fgets() return NULL which marks all the data has been read from file.

P.S - I hope you are already aware of file opening / closing operations using fopen()/ fclose().

Upvotes: 0

rbaleksandar
rbaleksandar

Reputation: 9691

From what I see in your example of points you have a specific separation of the points that is tabs and new lines. My suggestion is following:

  1. Write a loop that goes through every character in your TXT file
  2. Once a numeric character is detected activate a new state (a method) where you start the detection of a point UNTIL a tab ("\t") or a new line ("\n") is detected. Since you have a fixed formating you can use your

    scanf("%f %f", &x1, &x2);
    

    when you detect a numeric character (I suggest you use an array (since you have a fixed number of points) of points (a point being a struct with x,y as its members). You have to return one character backwards in order to detect the complete coordinate of the point since the first numeric character of your point was used to trigger the detection state.

  3. Once you detect a tab or a new line return to the loop and continue "eating up" tabs and new lines until the next numeric character.

In your example the parsing can look like this:

  1. Open file for reading and initialize array/list of points, set counter := 0;
  2. Loop through characters (ignore tabs and new lines) until EOF is reached or counter == 100;
  3. If numeric character detected parse pair of coordinates (use your scanf() here);
  4. Add point to array/list and increase counter
  5. goto 2;

Hope this helps. :)

Upvotes: 0

congusbongus
congusbongus

Reputation: 14622

scanf and family return a value that tells you how many values it managed to scan:

RETURN VALUE

  These functions return the number of input items successfully matched
   and assigned, which can be fewer than provided for, or even zero in
   the event of an early matching failure.

Thus, you can still use scanf, provided that you know the maximum number of points. Here's a sample program:

#include <stdio.h>
void read(char *line) {
    float x1 = 0, x2 = 0;
    int n = sscanf(line, "%f %f", &x1, &x2);
    printf("Read %d, %f %f\n", n, x1, x2);
}
int main(void) {
    char *line1 = "1.0";
    char *line2 = "1.0 2.0";
    read(line1);
    read(line2);
    return 0;
}

Output:

Read 1, 1.000000 0.000000
Read 2, 1.000000 2.000000

However, from the sounds of things 100 is a lot of numbers, so you could try tokenising using strtok and reading the values in a loop.

Upvotes: 1

Related Questions