Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to read a file with an unknown character set into a memory buffer?

Status
Not open for further replies.

Fedo

Technical User
Feb 6, 2001
9
US
I have a problem with which I have already spent a lot of time and I cannot find a solution although I intuitively feel that there is a very easy solution for it. I am completely stucked.
Here is the problem:
I have a file about which I do not know anything (neither its character set) and I want to read the whole file into a memory buffer.
I have already tried fread, fgets (fgetws), getline, streams, etc. The problem is that all those functions and techniques stop reading of the file as soon as they find 00x0 which they consifer for EOF.
Does anybody have an idea what I am doing wrong?
 
hFile = fopen("test.txt","rt");
FileBuffer = (char*)calloc(iFileLen+1, sizeof(char));
fread((void*)(FileBuffer), sizeof(char), iFileLen, hFile);
fclose(hFile);

Where iFileLen is a file size.
Regards.
 
read the file in binary mode. Use function feof(yourFile) to know, is the end or not. John Fill
1c.bmp


ivfmd@mail.md
 
Lim, thanks for the response. However, the code you propose to use does not work when you want to copy to a buffer a Microsoft Word document or a document with not 8-bit character set.
 
I should maybe make it more clear. I am able to read whichever text file into the memory which uses 8-bit character set. However files with not 8-bit character sets as well as Microsoft Word, Excel files I cannot read (the reading is stopped as soon as 00x0 character is found which is probably considered as EOF).
Here are 2 different approaches I use:

1.> using streams
AnsiString MainForm::ReadFile(char *MyFile)
{
ifstream in(MyFile); // Open for reading
ostrstream out;
out << in.rdbuf(); // Copy file
return (AnsiString(out.str()));
}

2.> using fread
AnsiString MainForm::ReadFile(char *MyFile)
{
FILE *stream;
AnsiString Buf=&quot;&quot;;
if ((stream = fopen((MyFile, &quot;r&quot;)) == NULL)
return (&quot;&quot;);
else {
fseek(stream, 0, SEEK_END);
float FileSize = ftell(stream);
fseek(stream, 0, SEEK_SET);
//Allocate a buffer.
char *Buffer = new char[FileSize+1];
//Read from the file
unsigned int ItemsRead = fread(Buffer, 1, FileSize, stream);
Buffer[ItemsRead] = 0; //Close with a 0 char.
//Load the contents of the buffer to the result-string.
Buf = AnsiString(Buffer);
//Delete buffer and close the file.
delete[] Buffer;
fclose(stream);
return (Buf);
}
}

In my test examle I try to write the memory buffer into the file:
void __fastcall MainForm::BtnClick(TObject *Sender)
{
FILE *stream;
AnsiString Out;

if ((stream = fopen(&quot;Output.zzz&quot;, &quot;w+&quot;)) == NULL)
ShowMessage (&quot;Error opening the file&quot;);
else
{
Out = ReadFile(&quot;My.doc&quot;);
fprintf(stream, Out.c_str());
fclose(stream);
}
}

As I mentioned none of those approaches reads a not 8-bit character set document or Word document. I have even tried to read a file byte by byte (using fgetc).
I am really stucked. Can anybody help me?
 
O.K.
I've finally got it. The mistake I did was not in reading a file, but in writing read memory buffer to another file. For writing I used function fprintf, which writes string (char *) to a file. The problem with this function is that writing stops as soon as 0x00 appears in the string (0x00 is considered as the end of the string). Therefore, you have to use either streams or function write, where it is possible to specify how many bytes from the buffer should be written to the file.
Here, I present my the most preferable solution to the problem. In this example I use streams and library strstream.

1.> using streams
void MainForm::ReadFile(char *MyFile, ostrstream *OutDoc)
{
// Open for reading
ifstream in(MyFile, ios_base::binary);
// Copy file into the String stream
*OutDoc << in.rdbuf();
}

In my test examle I try to write the memory buffer into the file:
void __fastcall MainForm::BtnClick(TObject *Sender)
{
ostrstream OutDoc;

// Open file
ofstream in(&quot;Output.zzz&quot;, ios_base::binary);
ReadFile(&quot;MyDoc&quot;, &OutDoc);
// Copy the String stream into the file
in << OutDoc.rdbuf();
}

Good luck.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top