1

I am writing a program that opens numerous text files and reads from them parameters for planetary bodies. I have a problem when reading the text files.

sample text file

 2
 1, 1, 2
 3.5, 3, 4

The first number (2) refers to the number of bodies found in the file. The next 2 lines correspond to the planet's parameters (x and y coordinates and mass respectively). I have 4 text files containing different amounts of bodies and need to store all the data in a variable.

my code

struct body {

float x;
float y;
float mass;

};

int main()
{

struct body b[8];
FILE *fp;
int i, j, k;
int num, count = 0;
char fName[10];

for (i = 1; i < 5; i++)    
{ 
    sprintf(fName,"bodies%d.txt",i);
    fp = fopen(fName, "r");

    if (fp == NULL)
    {   
        printf("Can't open %s \n",fName);
        exit(-1);
    }

    fscanf(fp, "%d", &num);


    for (j = count; j < num; j++)
    {               
        fscanf(fp, "%f%*c %f%*c %f%*c", &b[j].x, &b[j].y, &b[j].mass);
        printf("%f %f %f\n", b[j].x, b[j].y, b[j].mass);

        count = j;
    }               


}

It is reading the numbers from the text files, but it is stopping after 6 readings and there are 8 in total.

What could be the problem?

5
  • sprintf(fName,"bodies%d.txt",i); <-- Buffer overflow. fName can hold a maximum of 9 chars +1 for \0 at the end. You copy 12 chars into it(\0 included). Why do you have count? Commented May 9, 2015 at 8:01
  • 1
    count refers to the next position of the array Commented May 9, 2015 at 8:06
  • That's confusing and wrong. Think. When you do j = count, you check j < num . That's wrong. Use j=0 instead of j = count and it is better to use count++ instead of count=j. And in the loop, instead of b[j], use b[count]. And I don't like your way of hardcoding arrays(unless you know the number of bodies in each file beforehand). Commented May 9, 2015 at 8:15
  • suggest refactor functionality to a function eg. struct body *read_body(FILE *fp). and minimise your problem to one single call to this function Commented May 9, 2015 at 8:16
  • I understood the problem, very stupid mistake in fact. Corrected the loop, thanks! They are hardcoded because I already know the number of bodies in each file beforehand Commented May 9, 2015 at 8:20

2 Answers 2

1

Your code has some problems:

  1. fName is declared as

    char fName[10];
    

    and you use

    sprintf(fName,"bodies%d.txt",i);
    

    which writes 12 characters into fName(including the NUL-terminator) which can atmost hold 9 characters(+1 for the NUL-terminator).

  2. The for loop:

    for (j = count; j < num; j++)
    {               
        fscanf(fp, "%f%*c %f%*c %f%*c", &b[j].x, &b[j].y, &b[j].mass);
        printf("%f %f %f\n", b[j].x, b[j].y, b[j].mass);
    
        count = j;
    }
    

    has many problems and is confusing too. When you do j = count, you check j < num. This makes no sense as count is not related to num.

Fixes:

  1. For the first problem, allocate enough space for fName:

    char fName[12];
    

    instead of

    char fName[10];
    
  2. As for the second problem, use

    for (j = 0; j < num; j++) //j should be initialized to 0
    {               
        fscanf(fp, "%f%*c %f%*c %f%*c", &b[count].x, &b[count].y, &b[count].mass);
        printf("%f %f %f\n", b[count].x, b[count].y, b[count].mass); //Use b[count] instead of b[j]
    
        //count = j; Works, but the below is better
        count++;
    }
    
Sign up to request clarification or add additional context in comments.

Comments

1

Try replacing j = count with j = 0 in the second for loop.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.