By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,386 Members | 1,766 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,386 IT Pros & Developers. It's quick & easy.

Reading unknown number of variables with sscanf

P: 15
Hi,
I am using Mircosoft Visual C++ 6.0.
I am reading in a line from a .dat file using fgets. The line is an unknown number of variables written in scientific notation (4.20000e+00 1.00000e-01 1.177000e+00 0.000000e+00 ...). The first two are an x and y location and will always be there. Due to the number of these lines to read in, minimum is 500000, I don't want to use char/string as each number will take about double the memory of a float. Using sscanf with 30 %f I can find the number of variables (there may be up to 30).
Expand|Select|Wrap|Line Numbers
  1. int number = sscanf(data_in,"%f%f%f%f%f%f%f%f%f%f%f...",&temp[0],&temp[1],...,&temp[29]);
With number I can create a string with the correct number of '%f' and set the array to the correct length.
At the moment I use a full array of 30 with the correct number of %f. Knowing how many variables there are I can pull only the valid elements from the array.
I am stuck on how to set the number of references '&temp[n]', to match the number of %f in the format string.
Any ideas on how to set to everything equal lengths would be greatly appreciated.

Jim
Aug 30 '07 #1
Share this Question
Share on Google+
5 Replies


Expert 10K+
P: 11,448
Hi,
I am using Mircosoft Visual C++ 6.0.
I am reading in a line from a .dat file using fgets. The line is an unknown number of variables written in scientific notation (4.20000e+00 1.00000e-01 1.177000e+00 0.000000e+00 ...). The first two are an x and y location and will always be there. Due to the number of these lines to read in, minimum is 500000, I don't want to use char/string as each number will take about double the memory of a float. Using sscanf with 30 %f I can find the number of variables (there may be up to 30).
Expand|Select|Wrap|Line Numbers
  1. int number = sscanf(data_in,"%f%f%f%f%f%f%f%f%f%f%f...",&temp[0],&temp[1],...,&temp[29]);
With number I can create a string with the correct number of '%f' and set the array to the correct length.
At the moment I use a full array of 30 with the correct number of %f. Knowing how many variables there are I can pull only the valid elements from the array.
I am stuck on how to set the number of references '&temp[n]', to match the number of %f in the format string.
Any ideas on how to set to everything equal lengths would be greatly appreciated.

Jim
Did you know that scanf returns the number of items that were succesfully
converted? So scanf("%lf", &aVar) returns either 0 or 1; if it returned 1 you
should call it again and again until it returns 0. Keep track of a little index,
store the variable value somewhere etc. etc.

kind regards,

Jos
Aug 30 '07 #2

P: 15
Did you know that scanf returns the number of items that were succesfully
converted? So scanf("%lf", &aVar) returns either 0 or 1; if it returned 1 you
should call it again and again until it returns 0. Keep track of a little index,
store the variable value somewhere etc. etc.

kind regards,

Jos
The trouble is the line returned from fgets is one continuous string. To loop the number brought in needs to removed from the string or pointer location of the end of the read needs to be saved and used for the next read. Otherwise the first number in the string fills up the array. I looked at using strpbrk to find the spaces between the numbers and trim the string. The number of spaces between each number is not fixed (output file from another program which is not going to change). Do you know if there is a way to advance the pointer scanf uses to start the read?

Jim
Aug 30 '07 #3

Expert 10K+
P: 11,448
The trouble is the line returned from fgets is one continuous string. To loop the number brought in needs to removed from the string or pointer location of the end of the read needs to be saved and used for the next read. Otherwise the first number in the string fills up the array. I looked at using strpbrk to find the spaces between the numbers and trim the string. The number of spaces between each number is not fixed (output file from another program which is not going to change). Do you know if there is a way to advance the pointer scanf uses to start the read?

Jim
Don't fgets() the line first but let fscanf() read from the input stream directly.
After a fscanf() has succeeded check if the end of the line has been reached.
Note that you can put back characters to that same stream whenever needed.

The best solution would be a full fledged lexical analyzer but a bit of careful
reading as described above can do the job too.

kind regards,

Jos
Aug 30 '07 #4

P: 15
Don't fgets() the line first but let fscanf() read from the input stream directly.
After a fscanf() has succeeded check if the end of the line has been reached.
Note that you can put back characters to that same stream whenever needed.

The best solution would be a full fledged lexical analyzer but a bit of careful
reading as described above can do the job too.

kind regards,

Jos
Thanks for patience and help, my problem is solved and my code is cleaner. I avoided the lexical but will have to look into it.

Jim
Aug 30 '07 #5

Expert 10K+
P: 11,448
Thanks for patience and help, my problem is solved and my code is cleaner. I avoided the lexical but will have to look into it.

Jim
You're welcome of course; if you want to explore the lexical analyzer approach
google for lex, flex, zlex and maybe yacc and bison. Those links mention
alternatives as well. Good luck and

kind regards,

Jos
Aug 30 '07 #6

Post your reply

Sign in to post your reply or Sign up for a free account.