-
Program Looping Problem
I wrote a simple routine to read and load values from my currency exchange rates.csv file, but it appears to keep reading the first record. Because of this, my check for EOF never gets satisfied. What is the secret to advancing to the next record and read the rest of the file? I am including my code for your review.
Code:
float Curr_Conv_Factor; /* Individual currency conversion factor read from
file to be used to fill the array */
float Currency_Conv[24][24]; /* Array containg currency conversion factors */
int Row; /* Row position in currency conversion array */
int Column; /* Column poistion in currency conversion array */
fstream infile; /* Define/create object type to be used for accessing
the contents of the file. */
main()
{
infile.open( "currency exchange rates.csv", ios::in );
while( !infile.eof() )
{
for (Row = 0; Row < 24; Row++)
{
for (Column = 0; Column < 24; Column++)
{
infile >> Curr_Conv_Factor;
Currency_Conv[Row][Column] = Curr_Conv_Factor;
printf("\n Currency Conversion amount in %i, %i is", Row, Column);
printf("%f", Currency_Conv[Row][Column]);
infile >> Curr_Conv_Factor;
}
}
}
Code Tags Added by Kermi3
-
haha - use code tags bud...
what compiler are you using?
The reason I ask this is because there is a serious bug with Visual C++ 6 Enterprise. I ended up having to change compilers to Dev-cpp to do the job.
-
Program Looping Problem
I am using Dev-C++ 4. I see that my code is still not conforming to the standards of using code tags, sorry about that!
-
Do you think you could give us a sample of how data is structured in your file... I know its csv but still visuals make it easier for the rest of the board.
One way to advance is to select a certain byte in a file - however you are using sequential access files - not random access. I almost always work with data in random access and make structures to store the data. You would have to open your file in binary mode then use fileIn.seekg(int) to change file get position and fileIn.seekp(int) to change put position.
To find current position you can use int fileIn.tellp() and int fileIn.tellg()
hope this helps a little...
-
If you just select the code and then press the little # button on the editor pallet it will auto-insert code tags around your code.
Nice function! :-D
-
Program Looping Problem
Thanks for the help about the code tags. I am including 48 records from my *.csv file or two rows worth.
1.0000000,0.7785980,0.3613370,1.8514000,0.8285000, 0.1208240,0.1747490,1.2982000,0.1285890,0.0222220, 0.0095940,0.2631580,0.0881680,0.7086020,0.1596320, 0.6046680,0.1658810,0.0009350,0.0095350,0.1447010, 0.8553590,0.0306420,0.0249000,0.0005220
1.2843600,1.0000000,0.4640870,2.3778600,1.0640900, 0.1551820,0.2244400,1.6673600,0.1651550,0.0285410, 0.0123220,0.3379890,0.1132390,0.9101000,0.2050250, 0.7766110,0.2130520,0.0012010,0.0122460,0.1858480, 1.0985900,0.0393550,0.0319810,0.0006710
-
Ok - when I compile it all I get is 0.0000000
I'v narrowed it down to something..
If you declare your Curr_Conv_Factor as int and then get that value - it will work. But if your leave it float it will not. Why I dont know...
But there is a work around. You could treat the whole file as text in your program. Buffer the numbers up until the ',' then you could use atof() function
Example...
Code:
char x[] = "3.45643";
double y = 0;
y = atof(x);
-
Program Looping Problem
I changed the Curr_Conv_Factor to int like you suggested and recompiled and ran it. I still get only the first record read. I am new to this, this is why I am not sure why I have the problem.
-
Your problem is that you are using the extraction operator to read into a numeric variable, but your input contains non-numeric characters. Your program is not reading the same value over and over, it reads it once and encounters the comma at which point it stops reading (due to error) and each time through the loop your variable doesn't change.
Here's a simple (albeit not too elegant) fix that will get you around your woes:
Code:
#include <iostream>
#include <fstream>
#include <string>
int main() {
float Curr_Conv_Factor; /* Individual currency conversion factor read from
file to be used to fill the array */
float Currency_Conv[24][24]; /* Array containg currency conversion factors */
int Row; /* Row position in currency conversion array */
int Column; /* Column poistion in currency conversion array */
std::fstream infile; /* Define/create object type to be used for accessing
the contents of the file. */
infile.open( "in.csv", std::ios_base::in );
std::string field;
while( infile.good() ) {
// check if the file is still good in your inner loops too
for (Row = 0; Row < 24 && infile.good(); Row++) {
for (Column = 0; Column < 24 && infile.good(); Column++) {
if (Column == (24 - 1))
std::getline(infile, field);// last field on a line isn't comma-delimited
else
std::getline(infile, field, ',');// but the rest are
Curr_Conv_Factor = std::atof(field.c_str());// convert string to floating point numeric
Currency_Conv[Row][Column] = Curr_Conv_Factor;
std::printf("\n Currency Conversion amount in %i, %i is ", Row, Column);
std::printf("%f", Currency_Conv[Row][Column]);
}
}
}
return 0;
}
-
You're not dealing with all those comma's at all well.
Code:
for (Row = 0; Row < 24; Row++)
{
for (Column = 0; Column < 24; Column++)
{
infile >> Curr_Conv_Factor;
Currency_Conv[Row][Column] = Curr_Conv_Factor;
printf("\n Currency Conversion amount in %i, %i is", Row, Column);
printf("%f", Currency_Conv[Row][Column]);
infile.get(); // burn a comma
}
}
-
While my solution is useful for more general comma-delimited file parsing, Salem's is simple and perfect for your specific problem (comma-delimited numerics). The only thing you need to add to it is a check in your for loops that the file is still good, otherwise it'll just keep looping even though you've past the end of the file.
-
I have the code just like LuckY has listed above, but I have several errors now. Should I provide a list of the errors for further help?
-
Program Looping Problem
The code is as follows:
Code:
float Curr_Conv_Factor; /* Individual currency conversion factor read from
file to be used to fill the array */
float Currency_Conv[24][24]; /* Array containing currency conversion factors */
char Field;
int Row; /* Row position in currency conversion array */
int Column; /* Column position in currency conversion array */
std::fstream infile; /* Define/create object type to be used for accessing
the contents of the file. */
main()
{
std::fstream infile; /* Define/create object type to be used for accessing
the contents of the file. */
infile.open( "currency exchange rates.csv", std::ios_base::in );
std::string field;
while( infile.good() ) {
/* check if the file is still good in your inner loops too */
for (Row = 0; Row < 24 && infile.good(); Row++) {
for (Column = 0; Column < 24 && infile.good(); Column++) {
if (Column == (24 - 1))
std::getline(infile, field);/* last field on a line isn't comma-delimited */
else
std::getline(infile, field, ','); /* but the rest are */
Curr_Conv_Factor = std::atof(field.c_str()); /* convert string to floating point numeric */
Currency_Conv[Row][Column] = Curr_Conv_Factor;
std::printf("\n Currency Conversion amount in %i, %i is ", Row, Column);
std::printf("%f", Currency_Conv[Row][Column]);
}
}
}
return 0;
}
-
haha - your code tags still are not working - I notice you have an opening code tag but no closing. At the end of your code make sure you add [/CODE]
-
I editted my program portion of the message. Can someone please help me with it? I am not sure what is wrong. I think I have everything the way that was entered by LuckY's response.
-
The only thing that I noticed is that you didn't include any of the headers in the portion that you posted. After adding LuckY's includes, it worked compiled fine for me. Post a list of your errors.
-
Program Looping Problem
The errors I get are as follows:
Code:
c:\dev-c_~1\examples\curren~1.cpp:663: `::ios_base' undeclared (first use here)
c:\dev-c_~1\examples\curren~1.cpp:663: parse error before `::'
c:\dev-c_~1\examples\curren~1.cpp: At top level:
c:\dev-c_~1\examples\curren~1.cpp:686: ANSI C++ forbids declaration `USD_Menu' with no type
c:\dev-c_~1\examples\curren~1.cpp:686: new declaration `int USD_Menu()'
c:\dev-c_~1\examples\curren~1.cpp:55: ambiguates old declaration `void USD_Menu()'
c:\dev-c_~1\examples\curren~1.cpp:687: parse error before `}'
c:\dev-c_~1\examples\curren~1.cpp: In function `void USD_Menu()':
c:\dev-c_~1\examples\curren~1.cpp:696: new declaration `void USD_Menu()'
c:\dev-c_~1\examples\curren~1.cpp:686: ambiguates old declaration `int USD_Menu()'
I tried adding my complete program source for you too, but I think due to its size, it does not want to be added to this post. I will try to add it in a separate message and see if that works.
-
Program Looping Problem
This didn't work, do you have any suggestions? Should I include the program as a *.zipped attachment? If I do send it that way, do I need the code tags for this file too?
-
Sure, add a zip file. It doesn't need code tags.
-
Program Looping Problem
Here is a *zipped version of my program. I hope that this helps. Just as a reminder, I am using Dev-C++ version 4 as my compiler.
-
Why does this look like your previous question?
http://cboard.cprogramming.com/showthread.php?t=59682
A perfect illustration of how not to write code IMO.
That being, you don't write hundreds of lines of code without pressing compile, then worry about whether it's too big or not to dump on a message board for someone else to figure out.
Code:
do {
write_10_lines_of_code();
while ( compiler_returns_errors() ) {
fix_code_you_just_added();
}
} while ( program_not_finished() );
The point being that if errors suddenly appear, you've got a pretty good idea that it's got something to do with the 10 lines you just added.
> c:\dev-c_~1\examples\curren~1.cpp:663
600+ lines huh?
It's perfectly acceptable to create another project to test new ideas in to make sure you understand them fully, before trying to integrate them into your main project.
At least then if it all goes wrong, you have something more manageable to post to the board.
-
AQWst
Dont "throw your toys out of the pram" and send a moderator report for a response that you dont like. There's nothing "mean and nasty" about that reply, you should try to look at the response constructively and take in what's said.
-
Well, the only error is that somewhere around line 682, you have this:
Code:
}
return 0;
}
USD_Menu();
}
That will compile if you change it to this:
Code:
}
USD_Menu();
return 0;
}
Looks like you forgot a bit when you pasted. I make no guarantees as to the logical operation of this program. Run it and tell us if there's any more problems.
You might consider breaking your code up into a few different source code files. For instance, putting each nation's menu into a different file would help, as well as putting all the conversion constants into a header file.
-
I would echo Fordys point and would add that you are a new member. Telling us mods, who have been here for years what we do and don't need is "a trifle arrogant?"
-
Aside from that error pianorain mentioned, there are no syntactic errors. I am not a user of DevC++ but since using ios::in worked and ios_base::in doesn't, I'd recommend giving the former a try over the latter.
As an aside, your code could be streamlined considerably. You have the same blocks of code repeating throughout the entire file. Instead of having twenty-someought menus you could have a single menu that displays it's contents based on what current menu you are on (btw, your menus have too many rows to be displayed in a standard 80x25 screen).
-
I have the program compile down to two errors now. They are:
Code:
c:\dev-c_~1\examples\curren~1.cpp:663: `::ios_base' undeclared (first use here)
c:\dev-c_~1\examples\curren~1.cpp:663: parse error before `::'
-
Program Looping Problem
FYI, the program worked with all of the lines of code I added prior to adding the logic to read the *.csv file. This is the logic I added to hopefully remove the constants I have set up for each of the conversions.
-
See my previous post about that problem.
I added a little bit to your code to demonstrate how you can simplify your code considerably. Keep in mind it is only a start. Use the principles I've employed to revise your entire program. Good luck.
Here's the revised version. Just search for "lucky" to see where I made changes.