1. ## how to read info from text file?

Hi, I'm a beginner at programming and I'm not sure how to read in information from a text file. What I want to do is take a text file which contains around 20 rows and 3 columns of numbers, and put these into an array which can then be used for performing calculations. How do I do this? Would I need to declare the size of the array beforehand? When accessing my file, do I include the full address?

The relevant part is lines 29-33:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/* this is a simpllified code using BEM equations */

main()
{
int i;                          // counter for referring to rows of array
int Nb = 3;                     // number of blades
float pi=3.141592654;           // pi
float R=1;                      // radius of turbine (m)
float tsr=7;                    // tip speed ratio
float rho=1.225;                // density of air (kg/m^3)
float U=10;                     // free stream velocity of wind (m/s)
float maxchord=0.25;            // maximum allowed chord length (m)
float aguess = 0;               // initial guess for axial induction factor
float aprimeguess = 0;          // initial guess for tangential induction factor
float diff1 = 1;                // variable showing difference between axial induction factor and current guess
float diff2 = 1;                // variable showing difference between tangential induction factor and current guess
float delta_r = 0.01;           // this is the width of one blade element (m)
float opt_deltaQ = 0;            // optimum values of deltaQ
float alpha_deg, alpha_rad, Cl, Cd, Vr, chord, idealchord, phi, beta_rad, beta_deg, PTLfactor, a, aprime, solidity, deltaQ, omega, opt_alpharad, opt_phi, opt_chord;

float array[19][3];     // this declares an array

FILE*fp;
fp=fopen("c:\\flat plate test.txt", "r" );

/*for ( i = 0; i < 19; i++ )      // this inputs flat plate approximations for lift and drag into the array
{
array[i][0] = 5*i;    //alpha
array[i][1] = 2*sin(5*i*pi/180)*cos(5*i*pi/180);  //Cl
array[i][2] = 2*sin(5*i*pi/180)*sin(5*i*pi/180);  //Cd
}
*/
for (i=0; i<19; i++ )               // this runs through each set of values for alpha, Cl and Cd
{

alpha_deg = array[i][0];        // angle of attack, alpha, in degrees
Cl = array[i][1];               // coefficient of lift
Cd = array[i][2];               // coefficient of drag

while(diff1 > 0.0001 || diff2 >0.0001)                          // this runs the loop until the values for a and aprime have converged
{
phi = atan((U*(1-aguess))/(omega*dimRi*R*(1+aprimeguess))); // incoming flow angle (rad)
Vr = (U*(1-aguess))/sin(phi);                               // resultant wind velocity (m/s)
idealchord = (16*pi*U)/(9*Nb*Cl*tsr*dimRi*Vr);              // optimum chord length (m/s)
if(idealchord < maxchord) chord = idealchord;               // this limits the chord length if it exceeds the maximum
else chord = maxchord;                                      // allowed length defined by the variable maxchord
solidity = chord*Nb/(2*pi*dimRi*R);                         // solidity is ratio of blade area to swept area
PTLfactor = (2/pi)*acos(exp((Nb*(dimRi - 1))/(2*dimRi*sin(phi))));                        // Prandtl tip loss corrector factor
a = 1/((4*PTLfactor*sin(phi)*sin(phi))/(solidity*(Cl*cos(phi) + Cd*sin(phi))) + 1);       // axial induction factor
aprime = 1/((4*PTLfactor*sin(phi)*cos(phi))/(solidity*(Cl*sin(phi) - Cd*cos(phi))) - 1);  // tangential induction factor
diff1 = fabs(aguess -a);                                                                  // returns absolute difference between aguess and a
diff2 = fabs(aprimeguess - aprime);                                                       // returns absolute difference between aprimeguess and aprime
/*printf("ag= %1.4f a= %1.4f apg= %1.4f ap= %1.4f Vr= %3.3f ch= %1.3f phi= %1.4f \n", aguess, a, aprimeguess, aprime, Vr, chord, phi); */ //prints variables
aguess = a;             // redefines aguess for next iteration
aprimeguess =aprime;    // redefines aprimeguess for next iteration
}

deltaQ = 0.5*rho*U*(1-a)*omega*dimRi*dimRi*R*R*(1+aprime)*Nb*(Cl*sin(phi)-Cd*cos(phi))*chord*delta_r/(sin(phi)*cos(phi)); // torque produced by element

if(deltaQ > opt_deltaQ)     // this loop records the current variable values if they produce a higher deltaQ than any previous angle of attack
{
opt_deltaQ = deltaQ;
opt_phi = phi;
opt_chord = chord;
}
}

beta_deg= beta_rad*180/pi;    // setting angle beta, in degrees

printf("\n\noptimum deltaQ = %3.2f for beta = %2.2f deg, alpha = %2.1f deg, \nchord = %1.2f m at R = %1.1f m \n", opt_deltaQ, beta_deg, opt_alpharad*180/pi, opt_chord, dimRi*R);
}

2. Look up fscanf(), or use fgets() in combination with sscanf().

3. Thanks!
I've managed to get fgets partially working- it scans one line then stops. How would I make it scan the whole file?

4. Put it in a loop.

5. Check out the return type and return value of "fgets()". This should help you determine how to use it in a loop.

6. Thanks for the help everyone! In case anyone has the same problem, my code now looks like this:

relevant part is lines 28-45

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

/* this is a simplified code using BEM equations */

int main()
{
int i;                          // counter for referring to rows of array
int Nb = 3;                     // number of blades
float pi=3.141592654;           // pi
float R=1;                      // radius of turbine (m)
float tsr=7;                    // tip speed ratio
float rho=1.225;                // density of air (kg/m^3)
float U=10;                     // free stream velocity of wind (m/s)
float maxchord=0.25;            // maximum allowed chord length (m)
float aguess = 0;               // initial guess for axial induction factor
float aprimeguess = 0;          // initial guess for tangential induction factor
float diff1 = 1;                // variable showing difference between axial induction factor and current guess
float diff2 = 1;                // variable showing difference between tangential induction factor and current guess
float delta_r = 0.01;           // this is the width of one blade element (m)
float opt_deltaQ = 0;            // optimum values of deltaQ
float alpha_deg, alpha_rad, Cl, Cd, Vr, chord, idealchord, phi, beta_rad, beta_deg, PTLfactor, a, aprime, solidity, deltaQ, omega, opt_alpharad, opt_phi, opt_chord, dimRi;

float array[19][3];     // this declares an array

FILE * pFile;           // declares file
char mystring [1000];   // declares string to write file into
int j=0;                // counter for incrementing row of array to copy string into

pFile = fopen ("c:\\Users\\Shaun\\My Documents\\flat plate info.txt" , "r");    // this opens the specified file
if (pFile == NULL) perror ("Error opening the file");                           // gives error message if file can't be opened
else {
while(fgetc(pFile) != EOF){                                                 // runs loop until end of file
if ( fgets (mystring , 300 , pFile) != NULL )                               // gets string from the file provided there is no error
sscanf (mystring, "%f %f %f",&array[j][0], &array[j][1], &array[j][2]);     // takes values from the string and puts them into the array
j++;                                                                        // increments to next row of array
}
fclose (pFile);                                                             // closes file after use
}

for( dimRi=0.1; dimRi<1.01; dimRi=dimRi+0.05 )   //runs the code for various points along the radius
{
for (i=0; i<19; i++ )               // this runs through each set of values for alpha, Cl and Cd
{

alpha_deg = array[i][0];        // angle of attack, alpha, in degrees
Cl = array[i][1];               // coefficient of lift
Cd = array[i][2];               // coefficient of drag

while(diff1 > 0.0001 || diff2 >0.0001)                          // this runs the loop until the values for a and aprime have converged
{
phi = atan((U*(1-aguess))/(omega*dimRi*R*(1+aprimeguess))); // incoming flow angle (rad)
Vr = (U*(1-aguess))/sin(phi);                               // resultant wind velocity (m/s)
idealchord = (16*pi*U)/(9*Nb*Cl*tsr*dimRi*Vr);              // optimum chord length (m/s)
if(idealchord < maxchord) chord = idealchord;               // this limits the chord length if it exceeds the maximum
else chord = maxchord;                                      // allowed length defined by the variable maxchord
solidity = chord*Nb/(2*pi*dimRi*R);                         // solidity is ratio of blade area to swept area
PTLfactor = (2/pi)*acos(exp((Nb*(dimRi - 1))/(2*dimRi*sin(phi))));                        // Prandtl tip loss corrector factor
a = 1/((4*PTLfactor*sin(phi)*sin(phi))/(solidity*(Cl*cos(phi) + Cd*sin(phi))) + 1);       // axial induction factor
aprime = 1/((4*PTLfactor*sin(phi)*cos(phi))/(solidity*(Cl*sin(phi) - Cd*cos(phi))) - 1);  // tangential induction factor
diff1 = fabs(aguess -a);                                                                  // returns absolute difference between aguess and a
diff2 = fabs(aprimeguess - aprime);                                                       // returns absolute difference between aprimeguess and aprime
/*printf("ag= %1.4f a= %1.4f apg= %1.4f ap= %1.4f Vr= %3.3f ch= %1.3f phi= %1.4f \n", aguess, a, aprimeguess, aprime, Vr, chord, phi); */ //prints variables
aguess = a;             // redefines aguess for next iteration
aprimeguess =aprime;    // redefines aprimeguess for next iteration
}

deltaQ = 0.5*rho*U*(1-a)*omega*dimRi*dimRi*R*R*(1+aprime)*Nb*(Cl*sin(phi)-Cd*cos(phi))*chord*delta_r/(sin(phi)*cos(phi)); // torque produced by element

if(deltaQ > opt_deltaQ)     // this loop records the current variable values if they produce a higher deltaQ than any previous angle of attack
{
opt_deltaQ = deltaQ;
opt_phi = phi;
opt_chord = chord;
}
}

beta_deg= beta_rad*180/pi;    // setting angle beta, in degrees

printf("\n\nopt deltaQ = %3.2f for beta= %2.2fdeg, alpha= %2.1fdeg, chord= %1.2fm at R= %1.2fm\n", opt_deltaQ, beta_deg, opt_alpharad*180/pi, opt_chord, dimRi*R);
}
return 0;
}

7. How long will it take the OP to notice that he's lost the first character of every line?

8. I noticed that was happening, but I'm not sure how I would put read as the while test. Could you show me what that would look like?

9. Take out the fgetc and put the fgets where it is.
Code:
while(fgets(mystring , 300 , pFile) != NULL){                                                 // runs loop until end of file

10. What I want to do is take a text file which contains around 20 rows and 3 columns of numbers, and put these into an array which can then be used for performing calculations.
Code:
float array[19][3];     // this declares an array
"around 20 rows" means what? Does it mean it can be 20 rows, 21 rows, 22 rows, 19 rows? Your code doesn't look like it has limits on the j variable which means that your loop will keep trying to read into array indices that may not exist as long as it can successfully read a line from the file. As written, you at least need a check to make sure that you break out of the file read loop when j reaches 19.

11. Thanks tabstop, that fixed it.

12. Around 20 rows is a bit vague. In the code I posted, I just needed 19 rows, but depending on the file I am reading in, it could be a few more or less. So far, I've been counting the number of rows manually, and editing the size of the array before running the program, which works, but isn't ideal. Is it possible to declare an array with an unspecified number of rows, then let its size be defined by how much data I'm trying to put in? I haven't put a limit on the j variable for the same reason- it changes depending on how big the file is.

13. The easy way (though terribly inefficient, and with potential limitations) would be to declare your arrays with a number large enough to handle any cases you expect to encounter.

The better way would be to dynamically allocate memory as needed.

14. Originally Posted by mike112358
Around 20 rows is a bit vague. In the code I posted, I just needed 19 rows, but depending on the file I am reading in, it could be a few more or less. So far, I've been counting the number of rows manually, and editing the size of the array before running the program, which works, but isn't ideal. Is it possible to declare an array with an unspecified number of rows, then let its size be defined by how much data I'm trying to put in? I haven't put a limit on the j variable for the same reason- it changes depending on how big the file is.
Given the processing you're doing -- why store the data in the first place? Read a row, process it, compare it to current optimum and store new optimum if necessary, repeat.