![]() |
| | #1 |
| Registered User Join Date: Apr 2004
Posts: 20
| I have been going through the tutorials and making projects that utilize the new things that I have learned. I have gotten through File I/O, and my newest projects is making a Mad-Libs-like program. I have gotten everything down excepting the last step, and for the life of me I can't figure where I'm going wrong. I have made a small program that encapsulates the problem and allows for greater readability and all. I will give you the content of the two text files the program inputs from and the code of the small program. The program is meant to take the content of original.txt and, on certain words replace them with words from marker.txt I have been hitting an infinite loop. Check below to see where. Code: Text of original.txt: once upon an adjective dog , a cat decided to verb . done Code: Text of marker.txt: 4 odd 11 eat done once upon an odd dog , a cat decided to eat . Code: #include <fstream.h>
#include <iostream.h>
#include <string.h>
int main()
{
//my strings
char original[50];
char mark[50];
ofstream final("final.txt");
int spotter = 0; //counts the iteration of first while loop
int conv; //used for a conversion later
int indicator = 0; //used as a boolean
//my inputs - see above in post for contents
ifstream marker("markers.txt");
ifstream starter("original.txt");
while(strcmpi(original, "done")) //runs until original.txt hits word "done"
{
spotter = spotter + 1;
starter>>original;
indicator = 0;
marker.open("markers.txt"); //resets marker to beginning
while(strcmpi(mark, "done")) //runs until marker.txt hits word "done"
{
marker>>mark; //Alright, I have tinkered a bit already, and I'm pretty sure
//that this is where the problem lies. It just doesn't seem to
//be inputting anything. I'm stumped.
//This block of code is supposed to convert the string of numeric characters into integers
//In my Intro to CS class we use Java, and for this we have Integer.parseInt, so if
//a similar function exists in C++, let me know. But I don't think this is where the problem is.
if(strlen(mark) == 2)
{
conv = ((((int)mark[0] - 48) * 10) + ((int)mark[1] - 48));
}
else if(strlen(mark) == 3)
{
conv = ((((int)mark[0] - 48) * 100) + (((int)mark[1] - 48) * 10) + (((int)mark[2] - 48)));
}
else
{
conv = ((int)mark[0] - 48);
}
//So if the number in marker.txt is the iteration we are on...
if(conv == spotter)
{
marker>>mark; //1. takes next word out of marker.txt
starter>>original; //2. skips next word from original.txt
final<<mark; //3. inputs string from step 1
indicator = 1; //4. uses indicator like a boolean, see below
break;
}
}
if(indicator == 0) //if nothing happened in above loop...
final<<original; //input next word from original.txt and continue.
final<<" ";
}
final.close();
}
|
| Ilmater is offline | |
| | #2 | |
| Novice C++ Programmer Join Date: Nov 2003
Posts: 96
| Quote:
| |
| Padawan is offline | |
| | #3 |
| Registered User Join Date: Apr 2004
Posts: 20
| No, I guess I didn't. But I'm almost positive that that isn't where the problem lies. I'll describe some of the tinkering I've done to give you a better idea of what is going on. Change: Setting first while loop to a for loop Result: Infinite loop problem not fixed. Change: Setting second while loop to a for loop Result: No infinite loop, but doesn't change original.txt at all, just copies it into final.txt. Still, I kept this change so I could do the below stuff... Change: Adding line cout<<conv; after conv is calculated Result: Getting wierd results, like -480 or something. Change: Adding line cout<<mark; after mark is initialized in the loop Result: Nothing is printed, leaving me to believe that nothing is being inputted to mark. So that is what I have done so far. I hope this gives a better idea of the problem. Any input would be appreciated. |
| Ilmater is offline | |
| | #4 |
| Registered User Join Date: Jul 2003
Posts: 1,088
| Change this > ifstream marker("markers.txt"); to this ifstream marker; Also, look at atoi for your string to int conversion needs. And finally, <fstream.h> and <iostream.h> are non-standard. You might consider using the standard headers (<fstream> and <iostream>). Just look in the FAQ for good information on why and how. In addition, you might want to look into the standard string class in <string>, which in my opinion is easier to use than C-style strings. |
| jlou is offline | |
| | #5 |
| Registered User Join Date: Apr 2004
Posts: 20
| First of all, thanks! Second, I still have some issues. Using cout I have determined that the correct things are being inputted into mark, and atoi is working nicely with conv. Unfourtunately, original.txt is still just being copied into final.txt, and this time I have no idea why. Any ideas? Also, I could not find the stuff you are referring to in the FAQ. When I changed the header files and compiled, I got a bunch of errors telling me that all my strings and _fstreams were undeclared. So I'm kind of lost there. Last, where can I learn the basics of the standard string class? I really don't know anything about it. |
| Ilmater is offline | |
| | #6 |
| Registered User Join Date: Jul 2003
Posts: 1,088
| Ok, I couldn't find anything about the new headers in the FAQ either, so basically, when using the new, standard headers (without the .h) you must account for the fact that all the names that you use from those headers (like cout, cin, ifstream, etc.) are under the namespace std. There is a FAQ on namespaces here. It mentions some ways to account for the std namespace (that is why you got errors, the compiler didn't know cout was in the std namespace). I prefer to stay in the habit of appending "std::" to everything in those headers, since it makes my life easier in larger projects. Putting "using namespace std;" under the #includes is also fine for small projects like yours. I don't know a good tutorial about the standard string class, sorry. I'm sure there is more information if you search this site or google. In general, a good book is better for that kind of stuff, especially one that teaches C++ stuff like std::string immediately. If nobody has been able to help you I will try to look at your latest problem tomorrow. In the meantime, try using a debugger to narrow it down (again search the board or google for information on that ). |
| jlou is offline | |
| | #7 |
| Registered User Join Date: Jul 2003
Posts: 1,088
| If you haven't figured it out already, I found two things that will get you a lot closer. First, just opening the file again does not reset marker to the beginning. I'd suggest closing the file at the end of the while loop so that when it goes back through the open call will actually cause it to start at the beginning of that file again. You could probably also just seek to the beginning of the file. The second problem is that once you've gone through the marker file once, when you are done mark has a value of "done". Since you never reset that value, the next time through the outer while loop the inner while loop is skipped because mark already equals "done" from the last time. |
| jlou is offline | |
| | #8 |
| Registered User Join Date: Apr 2004
Posts: 20
| Thanks a bunch jlou! I understand what you mean with the errors, and I think I have fixed them. I'll post the newest version of the code: Code: #include <fstream>
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char original[50];
char mark[50];
ofstream final("final.txt");
int spotter = 0;
int conv;
int indicator = 0;
ifstream marker;
ifstream starter("original.txt");
while(strcmpi(original, "done"))
{
spotter = spotter + 1;
starter>>original;
indicator = 0;
marker.open("markers.txt");
marker>>mark;
while(strcmpi(mark, "done"))
{
conv = atoi(mark);
if(conv == spotter)
{
marker>>mark;
starter>>original;
final<<mark;
indicator = 1;
break;
}
marker>>mark;
}
if(indicator == 0)
final<<original;
final<<" ";
marker.close();
}
final.close();
cin.get();
return 0;
cin.get();
}
Any ideas this time? I'm possibly even more baffled. |
| Ilmater is offline | |
| | #9 |
| Registered User Join Date: Jul 2003
Posts: 1,088
| I have this as original.txt: Code: once upon an adjective dog , a cat decided to verb . done Code: 4 odd 11 eat done Code: once upon an odd dog , a cat decided to eat . done Make sure you don't have final.txt open in any editor when you run the program. I had it open in MSVC++, but I didn't realize it, so when I ran the program and opened the final.txt file it just brought the old results to the foreground. Ohh, and one last side note, if you want to move all the way up into the new standard headers, then change <string.h> to <cstring>. They are changing all of the C runtime library headers to remove the .h also, but they added the 'c' to the front for those that belong to the C library instead of the C++ library. Just remember that <cstring> replaces <string.h> but <string> is completely different. This ain't no big deal, but since you seemed open to the other suggestions I figured I'd mention it. Also, this site has more information on the different headers. |
| jlou is offline | |
| | #10 |
| Registered User Join Date: Apr 2004
Posts: 20
| My original.txt matches. My markers.txt matches. I even copy+pasted the code right into my compiler, compiled, and ran it. But original.txt is still just being copied into final.txt. I tested adding final<<"meh"; just to see if it was being rewritten, and it worked. So that isn't the problem. The only difference that I can see is that I am using Dev-C++ but I don't see how that would make a difference. Thanks again, though. |
| Ilmater is offline | |
| | #11 |
| Registered User Join Date: Jul 2003
Posts: 1,088
| Sorry, I was a little bit wrong with what I posted. With your code, I got: Code: once upon an odd , a cat decided to verb eat Maybe somebody with Dev-C++ handy can try and help. |
| jlou is offline | |
| | #12 |
| Registered User Join Date: Apr 2004
Posts: 20
| Ooh ooh! A clue, dear Watson! Altered code: Code: #include <fstream>
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char original[50];
char mark[50];
ofstream final("final.txt");
int spotter = 0;
int conv;
int indicator = 0;
ifstream marker;
ifstream starter("original.txt");
while(strcmpi(original, "done"))
{
spotter = spotter + 1;
starter>>original;
indicator = 0;
marker.open("markers.txt");
marker>>mark;
cout<<"OUTSIDE WHILE LOOP ITERATING"<<endl;
while(strcmpi(mark, "done"))
{
conv = atoi(mark);
cout<<"INSIDE WHILE LOOP ITERATING"<<endl;
if(conv == spotter)
{
marker>>mark;
cout<<"Conv is equal to spotter! Iteration: "<<spotter<<endl;
//starter>>original;
final<<mark;
indicator = 1;
break;
}
marker>>mark;
}
if(indicator == 0)
final<<original;
final<<" ";
marker.close();
}
final.close();
cin.get();
return 0;
cin.get();
}
Code: OUTSIDE WHILE LOOP ITERATING INSIDE WHILE LOOP ITERATING INSIDE WHILE LOOP ITERATING INSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING OUTSIDE WHILE LOOP ITERATING //That's twelve of them, btw |
| Ilmater is offline | |
| | #13 |
| Registered User Join Date: Apr 2004
Posts: 20
| Ok, after some investigation I have determined that the problem is that marker is not being reset to the beginning. So after the first iteration, it equals "done" and the inside while loop never iterates again. jlou mentioned "You could probably also just seek to the beginning of the file." That sounds like a possible solution, but all I know now is what the tutorial talked about (which amounts to reading from the file one string at a time). So can anyone explain to me how to do what jlou described? I can see the end in sight... |
| Ilmater is offline | |
| | #14 |
| Registered User Join Date: Mar 2002
Posts: 1,595
| look up seekg(). to set the file pointer to the beginning of the file: ifstreamName.seekg(0, ios::beg); should work, I think. Now just start reading through the file again. |
| elad is offline | |
| | #15 |
| Registered User Join Date: Apr 2004
Posts: 20
| It doesn't seem to be working. That is, after the first iteration, the inside while loop never iterates again, and mark stays equal to "done". I couldn't find anything so far on seekg(), but I'll continue looking. |
| Ilmater is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Newbie with Very Newbie Question | Jedi_Mediator | C++ Programming | 18 | 07-01-2008 08:00 AM |
| getting to grips with allegro and ms vc++ (newbie) | jimjamjahaa | C++ Programming | 4 | 11-18-2005 07:49 PM |
| Resource ICONs | gbaker | Windows Programming | 4 | 12-15-2003 07:18 AM |
| C++ newbie / linux not so newbie question | goldmonkey | C++ Programming | 7 | 12-13-2003 12:27 PM |
| Newbie Game Develpoers Unite! | Telenosis | Game Programming | 10 | 06-22-2002 02:02 PM |