• C

importing values from a text file and performing functions with them

I need to know how to import some variable values from a text file into my program.  I also need to know how to assign the variable x1, as an example, to the w value, given from the text file.
yumaslimAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

yumaslimAuthor Commented:
I meant assign x1 the value w from the text file, sorry.
Kent OlsenDBACommented:
Hi yumaslim,

There's lots of ways to do this.   One of the simplest is to read a file line by line and parse it with strtok().

Read a line.  Call strtok() using "=" as the separator.  Then examine the parameter for a known name.  When found, call strtok() again and then call atoi() on the returned parameter.  Set that value into the correct variable.


Good Luck!
Kent
Kent OlsenDBACommented:


Assume that the file contains:

DEBUG=0
WEIGHT=12
LENGTH=20

Then the program will contain:

  FILE *ini;
  char Buffer[100];
  char *Parameter;
  char *Value;

  ini = fopen ("Filename", "r");

  fgets (Buffer, 100, ini);
  Parameter = strtok (Buffer, ";");
  Value = strtok (NULL, ";");

  if (strcmp (Parameter, "DEBUG") == 0)
    Debug = atoi (Value);
etc....

Kent
yumaslimAuthor Commented:
Sorry, but I have no idea what you even told me to do.  This is part of an assignment in a beginning programming class and I've never seen any of that stuff before.  Is there a way to do this with a scanf statement?
Kent OlsenDBACommented:
Hi yumaslim,

Sure, you can use scanf() instead of fgets and strtok().

  FILE *ini;
  char Buffer[100];
  char Parameter[50];
  char Value[50];

  ini = fopen ("Filename", "r");

  fgets (Buffer, 100, ini);
  sscanf (Buffer, "%s=%s", Parameter, Value);

  if (strcmp (Parameter, "DEBUG") == 0)
    Debug = atoi (Value);
etc....

Kent
yumaslimAuthor Commented:
Unfortunately that's still too complicated for me.  And this was the easy way?  
Tim_UtschigCommented:
What is the current topic you are studying in your class?  How about the last few topics/chapters you've studied?
yumaslimAuthor Commented:
At this point we've only discussed printf and scanf statements, as well as the different types of variables.  We briefly went over flags, but very briefly.  We also went over a lot of shortcuts in C, such as var++ and var--.
yumaslimAuthor Commented:
Could someone explain what the sugguestion above means?  I assume it would work, but I have no idea what it does so it wouldn't actually help me.  Also, is there any easier way to do this?  The teacher made it seem like all we needed was a simple scanf statement, but that doesn't seem right.
Tim_UtschigCommented:
Quoting Kdo:
>  sscanf (Buffer, "%s=%s", Parameter, Value);

Given Buffer containing "a=b", Parameter will get "a=b" and Value will be left alone.

%s will keep reading until whitespace, so you'd need some whitespace before the equal sign.

Quoting yumaslim:
> At this point we've only discussed printf and scanf statements, as well as the different types of variables.

You must have discussed fopen() and fscanf().  Otherwise, how are you going to read from a file?  Shell redirection?

> The teacher made it seem like all we needed was a simple scanf statement, but that doesn't seem right.

You can replace Kdo's use of fgets() and sscanf() with fscanf().  E.g:

    fscanf (ini, "%s = %s", Parameter, Value);
yumaslimAuthor Commented:
I think I have gotten the values imported to my function, but now it won't compile.  I'll post my code.

1.      /*Program name: math_functions.c
2.      Author: John Colville
3.      Date created: February 09, 2006
4.      The purpose of this program is to import variable values from a text file
5.      and to perform several mid level math functions with them*/
6.      #include <stdio.h>
7.      int
8.      main(void)
9.      {double w, x, y, z, x1, x2, y1, y2, compute_distance, trigonometric,
10.      logarithmic;
11.      FILE *inp;
12.      inp = fopen("a3_inputs.txt", "w, x, y, z");
13.      fscanf(inp, "%s = %s", &w, &x, &y, &z);
14.      x1=w;
15.      x2=x;
16.      y1=y;
17.      y2=z;
18.      compute_distance= sqrt((x2-x1) exp(2) + (y2-y1) exp(2)):
19.      trigonometric= sin(x) + cos(y) + tan(z);
20.      logarithmic= log10(w) + log(x);
21.      printf("The four values read as imput are %g%g%g and %g\n" w, x, y, z);
22.      printf("The distance between (%g, %g) and (%g, %g) is %g\n" w, x, y,
23.      z,compute_distance);
24.      printf("The value of trigonometric(%g, %g, %g) is %g\n" w, x, y,
25.      trigonometric);
26.      printf("The value of logarithmic (%g, %g) is %g\n" w, x, logarithmic);
27.      printf("The smallest integer greater than or equal to %g is %g\n" x, w);
28.      printf("The largest integer smaller than or equal to %g is %g\n" y, w);
29.      return (0);
30.      }
Tim_UtschigCommented:
> 12.     inp = fopen("a3_inputs.txt", "w, x, y, z");

The second parameter is the open mode, and only "w" (by itself) is a valid mode, but you're reading, so you want "r".

> 13.     fscanf(inp, "%s = %s", &w, &x, &y, &z);

Your format specifyer specifies two strings, and you're passing it the addresses of four doubles.

Without resorting to more advanced concepts, you could use:

    fscanf(inp, "w = %lf", &w);
    fscanf(inp, "x = %lf", &x);
    fscanf(inp, "y = %lf", &y);
    fscanf(inp, "z = %lf", &z);

However your file will have to contain the values in that exact order.  E.g. the contents might be:

w = 1.1
x = 2.2
y = 3.3
z = 4.4

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
yumaslimAuthor Commented:
I'm still getting a parse error befor exp.  And I compiled it using -lm when compiling.
Tim_UtschigCommented:
You're missing a comma on line 22.
Tim_UtschigCommented:
Also missing a comma (in the same place) on all the rest of your printf() calls.

I'm tempted to give you the right answer for line 18, but I think you should learn that out on your own.  Here's a couple hints: you want pow() not exp(), and C doesn't evaluate like algebra.
yumaslimAuthor Commented:
where?  I caught that I put a colon at the end instead of a semicolon, but where does the comma go?
yumaslimAuthor Commented:
I actually already caught the commas in the printf() calls.  Thanks anyway though, stuff like that is sometimes hard to notice.
Tim_UtschigCommented:
    printf("The four values read as imput are %g%g%g and %g\n" w, x, y, z);

Should be:

     printf("The four values read as imput are %g%g%g and %g\n", w, x, y, z);

(and I doubt you want those first three values all jumbled together like that).
yumaslimAuthor Commented:
should I separate each %g by a comma as well, or a space?  I realized I forget the comma after the \n" when I looked at an older program.
yumaslimAuthor Commented:
I think I fixed the pow, but I'm still getting an error.  Oh and I'm trying to output the value to a3_output.txt, I left that out earlier.
yumaslimAuthor Commented:
Here's the new code:

1.      /*Program name: math_functions.c
2.      Author: John Colville
3.      Date created: February 09, 2006
4.      The purpose of this program is to import variable values from a text file
5.      and to perform several mid level math functions with them*/
6.      #include <stdio.h>
7.      #include <math.h>
8.      int
9.      main(void)
10.      {double w, x, y, z, x1, x2, y1, y2, compute_distance, trigonometric,
11.      logarithmic;
12.      FILE *inp;
13.      *outp;
14.      inp = fopen("a3_inputs.txt", "r");
15.      outp = fopen("a3_output.txt", "w");
16.      fscanf(inp, "w= %lf", &w);
17.      fscanf(inp, "x= %lf", &x);
18.      fscanf(inp, "y= %lf", &y);
19.      fscanf(inp, "z= %lf", &z);
20.      x1=w;
21.      x2=x;
22.      y1=y;
23.      y2=z;
24.      compute_distance= sqrt((pow((x2-x1),2) + (pow((y2-y1),2)));
25.      trigonometric= sin(x) + cos(y) + tan(z);
26.      logarithmic= log10(w) + log(x);
27.      fprintf("The four values read as imput are %g, %g, %g and %g\n", w, x, y,
28.      z);
29.      fprintf(outpt, "The distance between (%g, %g) and (%g, %g) is %g\n", w, x,
30.      y, z,compute_distance);
31.      fprintf(outpt, "The value of trigonometric(%g, %g, %g) is %g\n", w, x, y,
32.      trigonometric);
33.      fprintf(outp, "The value of logarithmic (%g, %g) is %g\n", w, x,
34.      logarithmic);
35.      fprintf(outp, "The smallest integer greater than or equal to %g is %g\n",
36.      x, w);
37.      fprintf(outp, "The largest integer smaller than or equal to %g is %g\n",
38.      y, w);
39.      return (0);
40.      }
Tim_UtschigCommented:
Have a look at each of your fprintf() calls.  I see a couple typos and an omission.

See if you can think of a way to combine lines 12 and 13 so that outp is the right type.
yumaslimAuthor Commented:
Alright, I think I fixed the things you pointed out.  However, I still don't know what is wrong with line 24; I'm still getting a parse error before the ' ; ' token.  Here is the new code:

1.      /*Program name: math_functions.c
2.      Author: John Colville
3.      Date created: February 09, 2006
4.      The purpose of this program is to import variable values from a text file
5.      and to perform several mid level math functions with them*/
6.      #include <stdio.h>
7.      #include <math.h>
8.      int
9.      main(void)
10.      {double w, x, y, z, x1, x2, y1, y2, compute_distance, trigonometric,
11.      logarithmic;
12.      FILE *inp,
13.      *outp;
14.      inp = fopen("a3_inputs.txt", "r");
15.      outp = fopen("a3_output.txt", "w");
16.      fscanf(inp, "w= %lf", &w);
17.      fscanf(inp, "x= %lf", &x);
18.      fscanf(inp, "y= %lf", &y);
19.      fscanf(inp, "z= %lf", &z);
20.      x1=w;
21.      x2=x;
22.      y1=y;
23.      y2=z;
24.      compute_distance= sqrt((pow((x2-x1),2) + (pow((y2-y1),2)));
25.      trigonometric= sin(x) + cos(y) + tan(z);
26.      logarithmic= log10(w) + log(x);
27.      fprintf(outp, "The four values read as imput are %f, %f, %f and %f\n", w,
28.      x, y, z);
29.      fprintf(outp, "The distance between (%f, %f) and (%f, %f) is %f\n", w, x,
30.      y, z, compute_distance);
31.      fprintf(outp, "The value of trigonometric(%f, %f, %f) is %f\n", w, x, y,
32.      trigonometric);
33.      fprintf(outp, "The value of logarithmic (%f, %f) is %f\n", w, x,
34.      logarithmic);
35.      fprintf(outp, "The smallest integer greater than or equal to %f is %f\n",
36.      x, w);
37.      fprintf(outp, "The largest integer smaller than or equal to %f is %f\n",
38.      y, w);
39.      fclose(inp);
40.      fclose(outp);
41.      return (0);
42.      }
Tim_UtschigCommented:
You're missing a closing parend on line 24.   And you could use a LOT less parenthesis, which would make mistakes like that easier to find.
yumaslimAuthor Commented:
Dang, I can't believe it was something that stupid.  Thanks for that, I thought I counted them all.  Now when I run the program I get a segmentation fault.  I've never gotten that before, what is it?
Tim_UtschigCommented:
A segmentation fault means your program tried to access memory it wasn't supposed to.  In this case it's probably because one of the fopen() calls failed and the pointer returned is not valid.

If you've learned "if" statements, then try testing inp and outp to see if they're equal to NULL (or simply false), and printing an error and returning out of main() to exit your program without executing the rest of the code.
yumaslimAuthor Commented:
how do I test if they are equal to null?
Tim_UtschigCommented:
Have you learned conditions yet?

    if(inp == NULL)

Or to test if inp is false:

    if(!inp)
yumaslimAuthor Commented:
Actually we didn't learn conditions yet, but we did learn if statements.  I put in the if statement
if(inp == NULL)
{printf("damn\n");}
and it read damn.  So that means that I'm not accessing a3_inputs.txt, right?
Tim_UtschigCommented:
> Actually we didn't learn conditions yet, but we did learn if statements.

If statements are useless without conditions.

> I put in the if statement
> if(inp == NULL)
> {printf("damn\n");}
> and it read damn.  So that means that I'm not accessing a3_inputs.txt, right?

Right.  Check that a3_inputs.txt exists in your current directory, and is readable.  If you're using Unix, run:

   cat a3_inputs.txt

or if you're using Windows, run:

   type a3_inputs.txt

And if the output is displayed, you should be good.

If you're using some sort of a graphical development environment, it might not be clear what your current directory is.
yumaslimAuthor Commented:
Ok, I ran cat a3_inputs.txt, but it  could not open file.  I labeled the file a3_input.txt.
Now the program writes to a3_output.txt, but I get a bunch of random numbers.

The four values read as imput are 0.000000, -76748645645134998259888824244475701
55957252205292896351904641551300640557769267075753586906738780531564512525106382
11858251350714936717770375019717280491933507257679410148523477790661059569783987
40857103046252931932793457473899006805697440091642695120804636695824460650302895
305589237465537973242271105024.000000, -2244553370006284362712181245225524518090
10904519321264227535145509408848252164083232879461690902119738725680537983173179
41481507661729080521367303139433928729371780969497108975945648012525281969402090
89893936130163812191497941556356719962641007827437334558660592028472576940680457
3524539265119966159643344896.000000 and 0.000000
The distance between (0.000000, -76748645645134998259888824244475701559572522052
92896351904641551300640557769267075753586906738780531564512525106382118582513507
14936717770375019717280491933507257679410148523477790661059569783987408571030462
52931932793457473899006805697440091642695120804636695824460650302895305589237465
537973242271105024.000000) and (-22445533700062843627121812452255245180901090451
93212642275351455094088482521640832328794616909021197387256805379831731794148150
76617290805213673031394339287293717809694971089759456480125252819694020908989393
61301638121914979415563567199626410078274373345586605920284725769406804573524539
265119966159643344896.000000, 0.000000) is Inf
The value of trigonometric(0.000000, -767486456451349982598888242444757015595725
22052928963519046415513006405577692670757535869067387805315645125251063821185825
13507149367177703750197172804919335072576794101485234777906610595697839874085710
30462529319327934574738990068056974400916426951208046366958244606503028953055892
37465537973242271105024.000000, -22445533700062843627121812452255245180901090451
93212642275351455094088482521640832328794616909021197387256805379831731794148150
76617290805213673031394339287293717809694971089759456480125252819694020908989393
61301638121914979415563567199626410078274373345586605920284725769406804573524539
265119966159643344896.000000) is -0.083336
The value of logarithmic (0.000000, -7674864564513499825988882424447570155957252
20529289635190464155130064055776926707575358690673878053156451252510638211858251
35071493671777037501971728049193350725767941014852347779066105956978398740857103
04625293193279345747389900680569744009164269512080463669582446065030289530558923
7465537973242271105024.000000) is -Inf
The smallest integer greater than or equal to -767486456451349982598888242444757
01559572522052928963519046415513006405577692670757535869067387805315645125251063
82118582513507149367177703750197172804919335072576794101485234777906610595697839
87408571030462529319327934574738990068056974400916426951208046366958244606503028
95305589237465537973242271105024.000000 is 0.000000
The largest integer smaller than or equal to -2244553370006284362712181245225524
51809010904519321264227535145509408848252164083232879461690902119738725680537983
17317941481507661729080521367303139433928729371780969497108975945648012525281969
40209089893936130163812191497941556356719962641007827437334558660592028472576940
6804573524539265119966159643344896.000000 is 0.000000
yumaslimAuthor Commented:
Here is my input file, a3_input.txt.

/*The inputs for math_funtions.c*/
w=10.0;
x=5.0;
y=13.2;
z=2.0
yumaslimAuthor Commented:
Why would it print all of that out?
Tim_UtschigCommented:
Put a space before the equal signs in your fscanf() format strings, and in your input file.  Otherwise the variables aren't getting set and they just contain whatever values happened to be in memory at the time your program started.
Tim_UtschigCommented:
Sorry, that wasn't the problem, the problem was the space *after* the equal sign in your fscanf() format strings.
yumaslimAuthor Commented:
I'm still getting the same problem.


1.      /*Program name: math_functions.c
2.      Author: John Colville
3.      Date created: February 09, 2006
4.      The purpose of this program is to import variable values from a text file
5.      and to perform several mid level math functions with them*/
6.      #include <stdio.h>
7.      #include <math.h>
8.      int
9.      main(void)
10.      {double w, x, y, z, x1, x2, y1, y2, compute_distance, trigonometric,
11.      logarithmic;
12.      FILE *inp,
13.      *outp;
14.      inp = fopen("a3_input.txt", "r");
15.      outp = fopen("a3_output.txt", "w");
16.      fscanf(inp, "w=%lf", &w);
17.      fscanf(inp, "x=%lf", &x);
18.      fscanf(inp, "y=%lf", &y);
19.      fscanf(inp, "z=%lf", &z);
20.      x1=w;
21.      x2=x;
22.      y1=y;
23.      y2=z;
24.      compute_distance=sqrt((pow((x2-x1),2))+(pow((y2-y1),2)));
25.      trigonometric=sin(x)+cos(y)+tan(z);
26.      logarithmic=log10(w)+log(x);
27.      fprintf(outp, "The four values read as imput are %f, %f, %f and %f\n", w,
28.      x, y, z);
29.      fprintf(outp, "The distance between (%f, %f) and (%f, %f) is %f\n", w, x,
30.      y, z, compute_distance);
31.      fprintf(outp, "The value of trigonometric(%f, %f, %f) is %f\n", w, x, y,
32.      trigonometric);
33.      fprintf(outp, "The value of logarithmic (%f, %f) is %f\n", w, x,
34.      logarithmic);
35.      fprintf(outp, "The smallest integer greater than or equal to %f is %f\n",
36.      x, w);
37.      fprintf(outp, "The largest integer smaller than or equal to %f is %f\n",
38.      y, w);
39.      fclose(inp);
40.      fclose(outp);
41.      return (0);
42.      }
yumaslimAuthor Commented:
What causes this problem?
Tim_UtschigCommented:
I just noticed your a3_input.txt contains a comment and some semicolons.  This is not C code.  This is all the file should contain:

w=10.0
x=5.0
y=13.2
z=2.0

And it appears you have to specify the \n after %lf in your fscanf() format strings.  I thought they would be automatically dealt with, but I was wrong.
yumaslimAuthor Commented:
Thank you I know that was a lot of work for such a small program.
Tim_UtschigCommented:
> Thank you I know that was a lot of work for such a small program.

No problem.  I hope I didn't give away the answers too easily.   I hope you learned from it.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.