Board index » cppbuilder » reading text files

reading text files


2006-07-19 03:22:28 AM
cppbuilder5
Hello
I'm trying to read a text file with this code:
FILE *fp;
AnsiString test1;
AnsiString test2;
AnsiString test3;
fp = fopen("c:\\windows\\desktop\\test.txt", "r");
if (!fp)
{
MessageBox(Handle,"Impossível visualizar arquivo","Erro",MB_OK + MB_ICONERROR );
}
fscanf(fp,"&test1\n",test1);
fscanf(fp,"&test2\n",test2);
fscanf(fp,"&test3\n",test3);
fclose(fp);
Label11->Caption = test1;
Label12->Caption = test2;
Label13->Caption = test3;
When I try to read, all labels go blank(like there are nothing on the file. What is wrong with my code?
Here is my text file:
15/06/2006
266
ENBCO
Renan
 
 

Re:reading text files

"Renan" < XXXX@XXXXX.COM >writes:
Quote
fscanf(fp,"&test1\n",test1);
fscanf(fp,"&test2\n",test2);
fscanf(fp,"&test3\n",test3);
Well, your format string is wrong, and fscanf doesn't work with
AnsiStrings. And the types it works with are pointers. I'm assuming
you meant to write something like:
fscanf(fp,"test1\n",&test1);
because that gives a pointer, at least. However, with your format
string, it won't work, and a pointer to AnsiString will result in
undefined behavior.
There is no safe way to use fscanf with AnsiString. However, if you
really plan to do it, you should set the string's length to the
appropriate value and then write into the pointer returned by c_str().
Oh, and be sure to guarantee you won't read lines that exceed that
length.
--
Chris (TeamB);
 

Re:reading text files

You are not using the function fscanf correctly. The second calling
parameter specifies the format specifier to use in reading from the file
stream. The third and following calling parameters to fscanf are the target
addresses, the addresses of the variables into which the values of the items
read are to be placed.
Your program uses "&test1\n" (or 2 or 3) as the format string. The
specification of the item to be read begins with a percent sign and none is
in the format string.
The target addresses are also wrong. They are not addresses of variables
into which the values read will be placed. Instead that code uses the names
of AnsiString class instances.
There also are other problems:
- if the call to fopen fails the code still calls fscanf using the
NULL file pointer
- the return value from fscanf is zero if there was an error
and it is not being checked
- the message box flags are bit patterns and should be or'd
and not arithmetically added
Maybe something like this would work better.
---------------------
// read a char* style string from a file
// remove the line feed/newline character from the string
// return it as an AnsiString
// if a NULL file pointer or bad read,
// returned value is an empty string
AnsiString ReadStringNoLF(FILE *fp)
{
char buffer[80];
if (!fp || !fgets(buffer, sizeof(buffer), fp))
{
buffer[0] = '\0'; // make the string empty
}
else
{
char *cr_location = strchr(buffer, '\n');
if (cr_location != NULL)
{
*cr_location = '\0'; // remove the '\n'
}
}
return AnsiString(buffer);
}
void __fastcall Form1::WriteCaptions(TObject *to)
{
FILE *fp;
fp = fopen("c:\\windows\\desktop\\test.txt", "r");
if (fp) // if the file opened ok
{
Label11->Caption = ReadStringNoLF(buffer, fp);
Label12->Caption = ReadStringNoLF(buffer, fp);
Label13->Caption = ReadStringNoLF(buffer, fp);
fclose(fp);
}
else
{
MessageBox(Handle,
"Impossível visualizar arquivo",
"Erro",
MB_OK | MB_ICONERROR );
}
}
---------------------
. Ed
"Renan" < XXXX@XXXXX.COM >wrote in message
Quote

Hello
I'm trying to read a text file with this code:
FILE *fp;
AnsiString test1;
AnsiString test2;
AnsiString test3;
fp = fopen("c:\\windows\\desktop\\test.txt", "r");
if (!fp)
{
MessageBox(Handle,"Impossível visualizar arquivo","Erro",MB_OK +
MB_ICONERROR );
}
fscanf(fp,"&test1\n",test1);
fscanf(fp,"&test2\n",test2);
fscanf(fp,"&test3\n",test3);
fclose(fp);
Label11->Caption = test1;
Label12->Caption = test2;
Label13->Caption = test3;

When I try to read, all labels go blank(like there are nothing on the
file. What is wrong with my code?

Here is my text file:
15/06/2006
266
ENBCO

Renan
 

{smallsort}

Re:reading text files

"Renan" < XXXX@XXXXX.COM >wrote:
Quote

Hello
I'm trying to read a text file with this code:
FILE *fp;
AnsiString test1;
[snip]
Well, as you are using VCL's AnsiString already, why not use
VCL for file access, too?
TStringList* pMyStringList = new TStringList;
pMyStringList->LoadFromFile("c:\\windows\\desktop\\test.txt");
Label11->Caption = pMyStringList->Strings[0];
Label12->Caption = pMyStringList->Strings[1];
Label13->Caption = pMyStringList->Strings[2];
delete pMyStringList;
 

Re:reading text files

"Thorsten Kettner" < XXXX@XXXXX.COM >wrote:
It works perfectly.
Could you post here this example of how to save text files with VCL?
Thanks
Quote
Well, as you are using VCL's AnsiString already, why not use
VCL for file access, too?

TStringList* pMyStringList = new TStringList;
pMyStringList->LoadFromFile("c:\\windows\\desktop\\test.txt");
Label11->Caption = pMyStringList->Strings[0];
Label12->Caption = pMyStringList->Strings[1];
Label13->Caption = pMyStringList->Strings[2];
delete pMyStringList;
 

Re:reading text files

"Renan" < XXXX@XXXXX.COM >wrote:
Quote
It works perfectly.
Could you post here this example of how to save text files
with VCL?
Strange question. Once you know about LoadFromFile, it's easy
to guess that there exists a SaveToFile which works vice versa,
no? This said, here is the unsurprising code:
TStringList* pMyStringList = new TStringList;
pMyStringList->Add(Label11->Caption);
pMyStringList->Add(Label12->Caption);
pMyStringList->Add(Label13->Caption);
pMyStringList->SaveToFile("c:\\windows\\desktop\\test.txt");
delete pMyStringList;
 

Re:reading text files

Thorsten Kettner wrote:
Quote
TStringList* pMyStringList = new TStringList;
...
delete pMyStringList;
Instead of this it is always better to do this:
std::auto_ptr<TStringList*>pMyStringList (new TStringList);
and the rest of the code is same, the only thing is that you do not
have to call delete, it will be called for you when variable goes out of
scope.
Darko
 

Re:reading text files

Quote
Strange question. Once you know about LoadFromFile, it's easy
to guess that there exists a SaveToFile which works vice versa,
no? This said, here is the unsurprising code:
I have done that question, because I'm new to c++ builder. I didn't use code anything. I just use to create hardware, others do create code to work with my hardware. Now I'm resposible to do all.
Thanks
Renan
 

Re:reading text files

"Darko Miletic" < XXXX@XXXXX.COM >wrote in message
Quote
Thorsten Kettner wrote:

>TStringList* pMyStringList = new TStringList;
...
>delete pMyStringList;

Instead of this it is always better to do this:

std::auto_ptr<TStringList*>pMyStringList (new TStringList);

and the rest of the code is same, the only thing is that you do not
have to call delete, it will be called for you when variable goes out of
scope.
Since the OP doesn't seem to be familliar with
these functions, it should also be mentioned that
they both throw exceptions on failure, so in addition
to your advice it should be more like (from memory...):
std::auto_ptr<TStringList*>pMyStringList (new TStringList);
try {
// fill up your list
// save to file
} catch(const &Exception e) {
// do something in case of failure
}
or alternately, just use fstream...
 

Re:reading text files

"Thorsten Kettner" < XXXX@XXXXX.COM >wrote:
Quote
Well, as you are using VCL's AnsiString already, why not use
VCL for file access, too?

TStringList* pMyStringList = new TStringList;
pMyStringList->LoadFromFile("c:\\windows\\desktop\\test.txt");
...
delete pMyStringList;
If this file c:\windows\desktop\test.txt doesn't exist, I'm going to get an error. How do I treat this error? I want to show a message box saying to the user that this file doesn't exist. I know how to show the message box, what I don't know is how to "catch" this error(don't know if this is the right word to express what I want to say).
Thanks
 

Re:reading text files

Darko Miletic < XXXX@XXXXX.COM >writes:
Quote
Instead of this it is always better to do this:

std::auto_ptr<TStringList*>pMyStringList (new TStringList);
Actually, that should be
std::auto_ptr<TStringList>pMyStringList (new TStringList);
(The template parameter should just be TStringList, and not have the *
in it. Afterall, the auto_ptr holds a pointer to a TStringList, not a
pointer to a pointer to a TStringList.)
--
Chris (TeamB);
 

Re:reading text files

Chris Uzdavinis (TeamB) wrote:
Quote
Actually, that should be

std::auto_ptr<TStringList>pMyStringList (new TStringList);
Yes, you are right. That is what happens when I type directly without
testing code first ;)
 

Re:reading text files

"Duane Hebert" < XXXX@XXXXX.COM >wrote in message
Quote
std::auto_ptr<TStringList*>pMyStringList (new TStringList);
std::auto+ptr<TStringList>...
Quote
} catch(const &Exception e) {
} catch (const Exception &e) {
Quote
or alternately, just use fstream...
No typo there...
 

Re:reading text files

"Duane Hebert" < XXXX@XXXXX.COM >writes:
Quote
"Duane Hebert" < XXXX@XXXXX.COM >wrote in message
news:44be2944$ XXXX@XXXXX.COM ...

>std::auto_ptr<TStringList*>pMyStringList (new TStringList);
std::auto+ptr<TStringList>...
std::auto_ptr
:)
--
Chris (TeamB);
 

Re:reading text files

"Chris Uzdavinis (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
"Duane Hebert" < XXXX@XXXXX.COM >writes:

>"Duane Hebert" < XXXX@XXXXX.COM >wrote in message
>news:44be2944$ XXXX@XXXXX.COM ...
>
>>std::auto_ptr<TStringList*>pMyStringList (new TStringList);
>std::auto+ptr<TStringList>...

std::auto_ptr

:)
I've been complaining that the new coffee here is
not strong enough...
Thanks :-)