Thankyou!!!!!!
That worked. Also I had to change that inbedded for loop part, because it didn't work.
Is there a way to leave out line endings during get, because it's working, only the map is missing the same characters at the end which match the number of newline characters in the file.
Just check if the character is '\n' and if it is then skip the rest of the loop.
Okay, wait, that's not what I want. It's output the file properly, just not the right amount of characters.
Hm, well, I fixed it. Not entirely sure but I think it's ok. I added 1 to the value of width. This caused the function to reprint the final character in the text file. So, as long as the text file end with a blank line, it should be ok. Thanks heaps for you help! For interests sake, here is the fixed function:
Thanks Again!Code:/*terrain.cpp - holds screen layout Anthony Arnold 2007 */ #include <fstream> #include <string> #include <vector> #include <iostream> #include "terrain.h" #include "array2d.h" using namespace Game; terrain::terrain (std::string fileName) { std::ifstream in(fileName.c_str()); if (!in) { throw GameException("Cannot open terrain file."); } else { std::string entry; std::string longFile; std::vector<string> stringVect; while (getline(in, entry)) { if (entry.size() > longFile.size()) { longFile = entry; } stringVect.push_back(entry); } height = stringVect.size(); width = longFile.size() + 1; in.close(); } in.clear(); in.open(fileName.c_str()); terrainArray = new Array2D<char>(width, height); char passTo; for( unsigned y = 0; y < height; y++ ) { for( unsigned x = 0; x < width; x++ ) { in.get(passTo); terrainArray->Put(x, y, passTo); } } in.close(); }
It seems to me that this:
Would be better written as:Code:std::string entry; std::string longFile; std::vector<string> stringVect; while (getline(in, entry)) { if (entry.size() > longFile.size()) { longFile = entry; } stringVect.push_back(entry); } height = stringVect.size(); width = longFile.size() + 1;
After all, you only want to know what is the size of the longest file (line), and to this end you do not actually need to record its content aside from putting it into the vector. In fact, you could even just reuse width and increment it at the end of this code block.Code:std::string entry; std::string::size_type longFileSize = 0; std::vector<std::string> stringVect; while (getline(in, entry)) { if (entry.size() > longFileSize) { longFileSize = entry.size(); } stringVect.push_back(entry); } height = stringVect.size(); width = longFileSize + 1;
Incidentally, this constructor could take its argument by const reference instead of value.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Are you sure you're getting the right output? What if the input file looks like this:Your array will look like this, right:Code:xxx xxxxx xxWhen you output the array it will look correct because of the newlines in it, but I don't think that's what you want.Code:xxx\nx xxxx\n xx\n\n\n
I don't think you need for loops at all. Just have x incremented each time in the while loop that gets a character. When you reach a newline character, you've reached the end of the file and you can reset x to 0 and increment y for the next line. Does that make sense? Is that what you want to do - mimic the input file in the array?
Well, it seems to output correctly, even if there are inconsistent line lengths. I think this is because of the nature of the Array2D class. The class basically created an array of size width * height. The reason I'm using it is so you can refer to a particular character on the map by its 2d position (w*h).
Also, the \n gets copied too, doesn't it? So when the output function (which is elsewhere in the program) see's \n it outputs it.
It doesn't screw up the line output, but it does throw the 2d array off. If there aren't the same amount of characters in the file as there are in the array (longest line * number of lines) then it will add on the last character in toPass until it fills it up. So:
Becomes:Code:xxx xxxxx xxCode:xxx xxxxx xxxxxxxxx
Exactly.
So assuming that's a problem, my post above gives one idea on how to fix it.
Did you mean something like this?
Because that didn't work either.Code:unsigned x = 0; unsigned y = 0; while (in.get(passTo)) { terrainArray->Put(x, y, passTo); if (passTo == '\n') { y++; x = 0; } else { x++; } }
>> Because that didn't work either.
What didn't work about it? There is one thing I can see that might be wrong with that, but I'm not sure.
It gave me a bit of junk output.
If you'd like more help solving that issue, please be more specific about the problems that come up. I won't guarantee that that algorithm is the correct one, but it makes sense to me and I think it should work. I and others can't help figure out why it doesn't work if we don't know what went wrong.
I'm sorry, there's just quite a bit of code here and I'm not quite sure how to explain how it all works. I'm sure you don't want me to post the entire program??? I've fixed the above algorith to work with 'non-rectangular' files, but I have hit yet another snag. If a particular line does not have as many lines as the longest one, the first part of that line is removed. It's all very confusing to me. If you don't understand anything, can you tell me exactly what else you need to know, because there's so much here, I don't know what else to tell you.
Currently, a file that looks like this will be output exactly as it is:
But a file that looks like this:Code:+---------+ | | +- +- | | +- | | + | +---+-----+
Outputs this:Code:+---------+ | | +- +- | +- | | + | +---+-----+
using the following algorithm:Code:+---------+ | | - +- +- | | + | +---+-----+
Code:char passTo; unsigned x = 0; unsigned y = 0; while(in.get(passTo)) { terrainArray->Put(x, y, passTo); x++; if (passTo == '\n') { terrainArray->Put(x - 1, y, ' '); terrainArray->Put(width - 1, y, '\n'); x = 0; if (y < height - 1) { y++; } else { break; } } }