PDA

View Full Version : c++ I/O problems



Jas
06-29-2008, 10:28 PM
Hey, everyone! I need to read in a file, modify it, and then output it to another file. Then that file needs to be read in, modified, and then output to yet another file. The problem is that I cannot use the getline() function, because there may or may not be new lines in the 100 MB file. Here is what I have, but it does not work:



char * text;
int len, pos, ending;

ifstream file_in ("test.txt");
ofstream file_out ("enc.txt");

pos = 0;
file_in.seekg(0, ios::end);
len = file_in.tellg();
ending = len;
file_in.seekg(pos, ios::beg);

while(len > 0){
if(len > 350){len = 350;}
text = new char[len];
file_in.read(text, len);
//modify text
file_out << text;
pos = file_in.tellg();
file_in.seekg(pos+len, ios::beg);
len = ending - pos;
}
file_in.close();
file_out.close();

file_in.open("enc.txt", ios_base::in);
file_out.open("unenc.txt", ios_base::out);

pos = 0;
file_in.seekg(0, ios::end);
len = file_in.tellg();
ending = len;
file_in.seekg(pos, ios::beg);

while(len > 0){
if(len > 350){len = 350;}
text = new char[len];
file_in.read(text, len);
//modify text
file_out << text;
pos = file_in.tellg();
file_in.seekg(pos+len, ios::beg);
len = ending - pos;
}
file_in.close();
file_out.close();


The first I/O section adds some characters to the end of the file, and the second ends up being an infinate loop because file_in.tellg() always equals -1. I am really lost, and I have been trying to do this for a few weeks, so any help would be great. Thanks.

magicyte
07-01-2008, 11:29 PM
First of all, why don't you include a library of some sort that your compiler provides? Such as iostream? It would be much easier to understand, for me, and maybe that will actually fix your problem. Try learning C. It is easier that C++ and you get to define everything on your own. By the way, use cout and cin for iostream. For cstdlib or stdlib, use printf("%s",char something="") and scanf("%s",char something=""). This may help you clarify the I/O part so that it is not self defined. As for the other part of your code, I do not understand what you are saying. Perhaps you could clarify your meaning.

-magicyte

Jas
07-02-2008, 04:40 AM
First of all, why don't you include a library of some sort that your compiler provides? Such as iostream? It would be much easier to understand, for me, and maybe that will actually fix your problem.


I included iostream and fstream. The reason the rest of the code it not posted is for security purposes (I would like to share as little code as posible that does not directly pertain to the problem, but I should have included that information, so I apologise).


Try learning C. It is easier that C++ and you get to define everything on your own.


Thanks, but I think I'll stick with C++, since the program is done except for this problem.


By the way, use cout and cin for iostream. For cstdlib or stdlib, use printf("%s",char something="") and scanf("%s",char something=""). This may help you clarify the I/O part so that it is not self defined.


Sorry for my ignorance, but what? Since I am not really familiar with C or C++, that makes no sense.



As for the other part of your code, I do not understand what you are saying. Perhaps you could clarify your meaning.


What part are we talking about? I would be happy to clear anything up for you.

If it is easier than sorting through my horrible chunk of code, maybe you can give me an example of what I am trying to do? (beleive it or not, the rest of the looks good and readable :))

Thanks for the reply, as well. I was wondering if anyone on DD knew anything about C++, lol.

magicyte
07-03-2008, 03:27 PM
I have a question. Where are the included libraries that will allow the I/O operations? If you have the COMPLETE CODE, please, let me see it. In order to actually help you with flying colors, I will need the whole code. Other than that, I do not know how the I/O operations work because there are no included libraries. Once again, in order to help you, I must see the complete code. Also, the getline() function may not work because it is included in a non-included file. Hopefully you reply.

-magicyte

Jas
07-03-2008, 04:21 PM
Thanks for the reply.


I have a question. Where are the included libraries that will allow the I/O operations?


Isn't there only one place they can be? But here is as much of the code as I can show.



#include <string>
#include <iostream>
#include <fstream>

using namespace std;

/*
* There is a class here I will not include
*/

int main(int arg_num, char* args[]){

char * text;
int len, pos, ending;

ifstream file_in ("test.txt");
ofstream file_out ("enc.txt");

pos = 0;
file_in.seekg(0, ios::end);
len = file_in.tellg();
ending = len;
file_in.seekg(pos, ios::beg);

while(len > 0){
if(len > 350){len = 350;}
text = new char[len];
file_in.read(text, len);
file_out << text;
pos = file_in.tellg();
file_in.seekg(pos+len, ios::beg);
len = ending - pos;
}
file_in.close();
file_out.close();

file_in.open("enc.txt", ios_base::in);
file_out.open("unenc.txt", ios_base::out);

pos = 0;
file_in.seekg(0, ios::end);
len = file_in.tellg();
ending = len;
file_in.seekg(pos, ios::beg);

while(len > 0){
if(len > 350){len = 350;}
text = new char[len];
file_in.read(text, len);
file_out << text;
pos = file_in.tellg();
file_in.seekg(pos+len, ios::beg);
len = ending - pos;
}
file_in.close();
file_out.close();


system("pause");

return 0;
}


I am not sure if that helps. Let me know.



Also, the getline() function may not work because it is included in a non-included file. Hopefully you reply.

I am not using that function. See the first post again:


The problem is that I cannot use the getline() function, because there may or may not be new lines in the 100 MB file.

The file is not likely to have new lines, because of the way it is generated (I won't go into that-- just trust me that there are few new lines, if any at all).

I am wondering, if it would be better just to ditch this code and start over. What do you suggest I do to accomplish what I need? (I need to read in 350 chars at a time to a string from a file, modify the string, insert it into another file, and to the same thing over again with the second file.)

Again, thanks for sticking with this.

magicyte
07-03-2008, 04:36 PM
It is actually all too confusing. The only way I can fix the script is if I have every single bit of code there is, just to understand it all (the code, that is). Alternatively, start over. I understand what the code is supposed to do, just not HOW it does it. If you could try to compile the code again and tell me the exact errors the compiler gives you, I may be able to understand what is wrong. All in all, starting over would be easiest. Three last things: One-Did you make the code? Two-Do you not want me to see the whole code because you are afraid of me stealing it (I WILL NOT STEAL THE CODE. HONEST.) Three-If it is VERY IMPORTANT, try to get it copyrighted.

-magicyte

magicyte
07-03-2008, 04:37 PM
And one last thing: Are you a black belt??

-magicyte

Jas
07-03-2008, 07:58 PM
It is actually all too confusing. The only way I can fix the script is if I have every single bit of code there is, just to understand it all (the code, that is). Alternatively, start over. I understand what the code is supposed to do, just not HOW it does it. If you could try to compile the code again and tell me the exact errors the compiler gives you, I may be able to understand what is wrong. All in all, starting over would be easiest.


Well, the rest of the code is only a class to modify the text input. There are also no compiler errors-- the problem is that the first block, namely this:


ifstream file_in ("test.txt");
ofstream file_out ("enc.txt");

pos = 0;
file_in.seekg(0, ios::end);
len = file_in.tellg();
ending = len;
file_in.seekg(pos, ios::beg);

while(len > 0){
if(len > 350){len = 350;}
text = new char[len];
file_in.read(text, len);
file_out << text;
pos = file_in.tellg();
file_in.seekg(pos+len, ios::beg);
len = ending - pos;
}
file_in.close();
file_out.close();

Somehow reads in some additional giberish after the file ends, and the second block, namely this:


file_in.open("enc.txt", ios_base::in);
file_out.open("unenc.txt", ios_base::out);

pos = 0;
file_in.seekg(0, ios::end);
len = file_in.tellg();
ending = len;
file_in.seekg(pos, ios::beg);

while(len > 0){
if(len > 350){len = 350;}
text = new char[len];
file_in.read(text, len);
file_out << text;
pos = file_in.tellg();
file_in.seekg(pos+len, ios::beg);
len = ending - pos;
}
file_in.close();
file_out.close();

is an infinate loop for some reason. I agree that starting over is probably the best solution, but I have done that at least five times and I have no idea where to start. Do you have any suggestion?



Three last things: One-Did you make the code? Two-Do you not want me to see the whole code because you are afraid of me stealing it (I WILL NOT STEAL THE CODE. HONEST.) Three-If it is VERY IMPORTANT, try to get it copyrighted.


1) Yes, otherwise it would probably work :p 2) No, it's nothing like that. However, the software is for security purposes so I don't want to show it. And at any rate the class shouldn't be needed-- it's basically irrelevant to the problem. (When text is read in from a file, that class modifies it before sending it to the output file.) Without the file I/O, the class works perfectly. 3) It's not that important.


And one last thing: Are you a black belt??

Yes :) 3rd Dan in Tae Kwon Do.

In the second block, the reason for the infanite loop is that this line:

pos = file_in.tellg();
Always sets pos to-1 (thus pos - the file length is 1, which the loop thinks is another character to read in so the loop starts again), but I don't know why that is.

magicyte
07-04-2008, 01:32 AM
No, sir. I do not have any suggestion on where to start next. Im just a kid.

-magicyte

Jas
07-04-2008, 02:12 AM
You know more about C++ than I do. :)

Let me put it like this: how would you go about it, if you were to code it? For example, what function(s) would you use?

Any information you can give me would be fantastic-- I have been working on this for weeks with no success. Trust me, you can't hurt anything worse than it already is.

magicyte
07-05-2008, 12:49 AM
Well, if I were to code this all, I would make a .dev file, first of all to compile the code together so that everything has easy access to eachother. Some functions I would use from other C++ libraries might be printf()/scanf() or cout/cin (of course). As for the other files retrieving whatever you said they would, I am stuck. I don't really know much about transporting information through files. If you are running the codes with MS-DOS, I do. Simply in the parameter section of the main() function include int argc for integers that will be collected from MS-DOS and char argv[]* (i think that is correct syntax, but not sure) to collect characters that will be used through other files. As for direct correspondence between C++ and C files, I do not know. As for direct correspondence between HTML, ASP, PHP, and XML files I do know. Unluckily, I cannot help you with the whole project. I may be able to give you small hints to other functions that you would know about, but I am a pure novice in C++. I am a GENIUS in C, as you may have seen in my signature below and/or previously. Right now I am taking classes from a professional C programmer and learning C++ from a mere book. Books can help a lot, and one book, C++ Unleashed by Jesse Liberty (can be bought over Amazon.com) would really help. Although you would rather stick to C++, it is easier to understand and define things in C. Just a suggestion. I'm more of an HTML, XML, AJAX, JavaScript kind of guy, cause everything in those languages are predefined. No compiling to go through, either. When you have a pre-defined language like C++ and you are compiling it, and all of the sudden an error comes up, it takes FOREVER to find the source of that error, even if it tells you what and where the error is (that is the compiler). And finally I am ending this long post. Even though I cannot help you, I will care to take a look at your script one last time to see how it is. Now for the FUN stuff. Once again, I am just a child who likes to program and types quickly, unlike OTHER children. Good luck with your code by the way. I will get back to you on your code as soon as I can. Hopefully I will find a solution.

-magicyte

DimX
07-05-2008, 08:06 PM
Jas, try this solution and see if it fits your needs:


#include <iostream>
#include <fstream>

using namespace std;

/* Prototype for the callback function.
*
* 1st param - a data chunk
* 2nd param - size of the data chunk
*
* returns - new transformed data, the WalkFile function automatically deletes
* it with the delete[] operator, so make sure you allocate it with the new[]
* operator also the second parameter must be set to the size of this data
*/
typedef char* (*walk_func_t)(const char*, int&);

/* Reads chunks of a given size from the input file and lets the given callback
* function transform the data, then writes the result to the output file.
*
* aInFilename - input file name
* aOutFilename - output file name
* aChunkSize - size of a single data chunk to read from the input file
* aWalkFunc - callback function which will be called with a data chunk passed to it
*/
void WalkFile(const char* aInFilename, const char* aOutFilename, int aChunkSize, walk_func_t aWalkFunc)
{
ifstream fin(aInFilename);
ofstream fout(aOutFilename);

char* bufferIn = new char[aChunkSize];

while (fin.good())
{
fin.read(bufferIn, aChunkSize);

int bufSize = fin.gcount();
char* bufferOut = (*aWalkFunc)(bufferIn, bufSize);

if (bufferOut != NULL && bufSize > 0)
fout.write(bufferOut, bufSize);

delete[] bufferOut;
}

delete[] bufferIn;
fout.close();
fin.close();
}

// Sample transform function (turns data uppercase)
char* Encode(const char* aData, int& aSize)
{
// If the size of the output buffer is different than the size of the input
// buffer, the aSize variable has to be modified!
char* dataOut = new char[aSize];

for (int i = 0; i < aSize; ++i)
dataOut[i] = toupper(aData[i]);

return dataOut;
}

// Sample transform function (turns data lowercase)
char* Unencode(const char* aData, int& aSize)
{
// If the size of the output buffer is different than the size of the input
// buffer, the aSize variable has to be modified!
char* dataOut = new char[aSize];

for (int i = 0; i < aSize; ++i)
dataOut[i] = tolower(aData[i]);

return dataOut;
}

int main(int argc, char* args[])
{
WalkFile("test.txt", "enc.txt", 350, &Encode);
WalkFile("enc.txt", "unenc.txt", 350, &Unencode);

cout << "Press ENTER to quit . . .";
cin.ignore();
return 0;
}


Basically, you have to call the WalkFile function and pass the names of the in/output files, size of the data to read at a time and the callback function. The latter will receive a chunk of data and will have to return a new one with the modified contents. See comments for more info.

The problem you may encounter is that you may want to call a non-static member function of your class, if that's the case then the code has to be modified, ask if you need further details.

Jas
07-13-2008, 03:13 PM
Thank you, DimX. I already managed to solve the problem, but thanks for the code. :)

magicyte
07-18-2008, 01:58 AM
Yeah. Um, I wuz gunner post that script too...

Sorry I couldn't get to you earlier (actually, I feel more sorry for myself cuz I didern't get thankt). It was after this last post you gave that I studied my C book a little bit. I then found out about File I/O!! Heh, now I know how to I/O between files!

-magicyte

Jas
07-18-2008, 11:09 PM
Heh. That's life, isn't it? You always get answers when their no longer needed. :D (I'm talking about myself here)

Well, thanks for trying to help :) Nice avatar, BTW.

magicyte
07-28-2008, 07:51 PM
Thanks and you too!

-magicyte