Connecting Tech Pros Worldwide Forums | Help | Site Map

Problem: writing to a file with C and reading with C++

Keith Dewell
Guest
 
Posts: n/a
#1: Jul 19 '05
Greetings!

My current job has brought me back to working in C++ which I haven't
used since school days. The solution to my problem may be trivial but
I have struggled with it for the last two days and would appreciate
this group's helpful expertise.

My problem may be related to mixing the C and C++ languages together.
Namely, I have a struct which I cannot change (as legacy code)
similiar to this (I will change the names throughout as I am working
on a government project):

typedef struct {
char firstMember[16];
char secondMember[16];
char thirdMember[96];
unsigned long count;
} my_Struct_T;

Instances of this struct are written to a file using fprintf like
this:

if (file_p) fprintf(file_p, MY_MACRO_FORMAT);

where MY_MACRO_FORMAT is defined like this:

#define MY_MACRO_FORMAT \
"%-12.12s\t%-8.8s\t%6d\t%-56.56s\t", \
aStruct.firstMember,aStruct.secondMember,aStruct.c ount,Struct.thirdMember

(aStruct being an instance of my_Struct_T)

The user selects the written file using a dialog box from the GUI in
order to read-in this data. To do this I use C++ code as follows:

std::vector<std::string> dataFromFile;
std::string aString;

//actually passed-in from another method
std::ifstream inputFileStream(&filename[0], std::ios::in);

while(std::getline(inputFileStream[0], aString, '\t'))
dataFromFile.push_back(aString);

Now the problem ...

Stepping through the code in the debugger as values are written to the
vector, I see that the values for aStruct.thirdMember are always
garbage unless it contains 15 or less characters.

BTW, the values always look good in the file to which I have written,
regardless of the number of characters for thirdMember. (I confirm
this with a text editor.)

Please offer a solution where I can still take a C++ approach (instead
of C) as that is my preference, while not changing the legacy code
(namely, the struct above).

Much Thanks,
Keith



Kevin Goodsell
Guest
 
Posts: n/a
#2: Jul 19 '05

re: Problem: writing to a file with C and reading with C++


Keith Dewell wrote:
[color=blue]
> Greetings!
>
> My current job has brought me back to working in C++ which I haven't
> used since school days. The solution to my problem may be trivial but
> I have struggled with it for the last two days and would appreciate
> this group's helpful expertise.
>
> My problem may be related to mixing the C and C++ languages together.
> Namely, I have a struct which I cannot change (as legacy code)
> similiar to this (I will change the names throughout as I am working
> on a government project):
>
> typedef struct {
> char firstMember[16];
> char secondMember[16];
> char thirdMember[96];
> unsigned long count;
> } my_Struct_T;
>
> Instances of this struct are written to a file using fprintf like
> this:
>
> if (file_p) fprintf(file_p, MY_MACRO_FORMAT);
>
> where MY_MACRO_FORMAT is defined like this:
>
> #define MY_MACRO_FORMAT \
> "%-12.12s\t%-8.8s\t%6d\t%-56.56s\t", \
> aStruct.firstMember,aStruct.secondMember,aStruct.c ount,Struct.thirdMember
>
> (aStruct being an instance of my_Struct_T)
>
> The user selects the written file using a dialog box from the GUI in
> order to read-in this data. To do this I use C++ code as follows:
>
> std::vector<std::string> dataFromFile;
> std::string aString;
>
> //actually passed-in from another method
> std::ifstream inputFileStream(&filename[0], std::ios::in);[/color]

What is 'filename'? If it's a std::string, this is very bad (use
filename.c_str() instead). If it's a char* or char[] this is
unnecessary. The only case I can think of where you'd want to do this is
if filename just happened to be a null-terminated vector<char>, which is
unusual.
[color=blue]
>
> while(std::getline(inputFileStream[0], aString, '\t'))
> dataFromFile.push_back(aString);[/color]

It's hard to say what this will do without knowing something about the
format of the file. Those char[] members you wrote to the file, might
they have tab characters in them?
[color=blue]
>
> Now the problem ...
>
> Stepping through the code in the debugger as values are written to the
> vector, I see that the values for aStruct.thirdMember are always
> garbage unless it contains 15 or less characters.
>
> BTW, the values always look good in the file to which I have written,
> regardless of the number of characters for thirdMember. (I confirm
> this with a text editor.)
>
> Please offer a solution where I can still take a C++ approach (instead
> of C) as that is my preference, while not changing the legacy code
> (namely, the struct above).[/color]

Your problem does not appear to have anything to do with "mixing C and
C++." There is nothing obviously wrong here (other than the
'&filename[0]' thing). Try posting a complete, minimal program that
demonstrates the problem, as well as some input to test it with.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Julián Albo
Guest
 
Posts: n/a
#3: Jul 19 '05

re: Problem: writing to a file with C and reading with C++


Keith Dewell escribió:
[color=blue]
> Stepping through the code in the debugger as values are written to the
> vector, I see that the values for aStruct.thirdMember are always
> garbage unless it contains 15 or less characters.
> BTW, the values always look good in the file to which I have written,
> regardless of the number of characters for thirdMember. (I confirm
> this with a text editor.)[/color]

If I understand you correctly the program works fine, the problem is how
to see correctly a non zero terminated array of char in the debugger. To
get help about that, post in a group about your development tools.

Regards.
Keith Dewell
Guest
 
Posts: n/a
#4: Jul 19 '05

re: Problem: writing to a file with C and reading with C++


Julián Albo <JULIANALBO@terra.es> wrote in message news:<3F71F31D.419B962A@terra.es>...[color=blue]
> Keith Dewell escribi? :[/color]


[color=blue]
>[color=green]
> > Stepping through the code in the debugger as values are written to the
> > vector, I see that the values for aStruct.thirdMember are always
> > garbage unless it contains 15 or less characters.
> > BTW, the values always look good in the file to which I have written,
> > regardless of the number of characters for thirdMember. (I confirm
> > this with a text editor.)[/color]
>
> If I understand you correctly the program works fine, the problem is how
> to see correctly a non zero terminated array of char in the debugger. To
> get help about that, post in a group about your development tools.
>
> Regards.[/color]

Thanks for responding. I am using MS Visual Studio 7.0 (a.k.a. MS
Visual C++ .NET) and watch the vector become populated by using:

dataFromFile._Myfirst, 10

in the watch window of the debugger.

The other members of the struct show good data in the debugger, only
thirdMember shows garbage. This is why I believe this is an I/O
problem since the data looks good in the file I am reading and this is
the only variable where I see garbage; all the other members of the
struct show good data in the debugger as they come into the vector.

Regards,
Keith
Julián Albo
Guest
 
Posts: n/a
#5: Jul 19 '05

re: Problem: writing to a file with C and reading with C++


Keith Dewell escribió:
[color=blue]
> The other members of the struct show good data in the debugger, only
> thirdMember shows garbage. This is why I believe this is an I/O
> problem since the data looks good in the file I am reading and this is
> the only variable where I see garbage; all the other members of the
> struct show good data in the debugger as they come into the vector.[/color]

Forget the debugger for one moment, and check the chars indvidually in
the program, then you will know if it is a problem with the debugger or
not.

If it is a program with the debugger ask in a windows programming group,
debuggers and compiler specific things are off-topic here.

Regards.
Keith Dewell
Guest
 
Posts: n/a
#6: Jul 19 '05

re: Problem: writing to a file with C and reading with C++


Kevin Goodsell <usenet1.spamfree.fusion@neverbox.com> wrote in message news:<C2lcb.1843$NX3.421@newsread3.news.pas.earthl ink.net>...[color=blue]
> Keith Dewell wrote:
>[color=green]
> > Greetings!
> >
> > My current job has brought me back to working in C++ which I haven't
> > used since school days. The solution to my problem may be trivial but
> > I have struggled with it for the last two days and would appreciate
> > this group's helpful expertise.
> >
> > My problem may be related to mixing the C and C++ languages together.
> > Namely, I have a struct which I cannot change (as legacy code)
> > similiar to this (I will change the names throughout as I am working
> > on a government project):
> >
> > typedef struct {
> > char firstMember[16];
> > char secondMember[16];
> > char thirdMember[96];
> > unsigned long count;
> > } my_Struct_T;
> >
> > Instances of this struct are written to a file using fprintf like
> > this:
> >
> > if (file_p) fprintf(file_p, MY_MACRO_FORMAT);
> >
> > where MY_MACRO_FORMAT is defined like this:
> >
> > #define MY_MACRO_FORMAT \
> > "%-12.12s\t%-8.8s\t%6d\t%-56.56s\t", \
> > aStruct.firstMember,aStruct.secondMember,aStruct.c ount,Struct.thirdMember
> >
> > (aStruct being an instance of my_Struct_T)
> >
> > The user selects the written file using a dialog box from the GUI in
> > order to read-in this data. To do this I use C++ code as follows:
> >
> > std::vector<std::string> dataFromFile;
> > std::string aString;
> >
> > //actually passed-in from another method
> > std::ifstream inputFileStream(&filename[0], std::ios::in);[/color]
>
> What is 'filename'? If it's a std::string, this is very bad (use
> filename.c_str() instead). If it's a char* or char[] this is
> unnecessary. The only case I can think of where you'd want to do this is
> if filename just happened to be a null-terminated vector<char>, which is
> unusual.
>[/color]
'filename' is an instance of FXString from the FOX Toolkit
(http://www.fox-toolkit.org/); in our shop we use FOX instead of MFC
or whatever for GUI development. We use a dialog box for the user to
give the filename and this code uses FOX. I agree that '&filename[0]'
is ugly, but it is the only way I have found, so far, that works.
FXString does not understand c_str(). Anyway, this doesn't pertain to
my problem since this code successfully attaches the stream to the
file. But thanks for your input![color=blue][color=green]
> >
> > while(std::getline(inputFileStream[0], aString, '\t'))
> > dataFromFile.push_back(aString);[/color]
>
> It's hard to say what this will do without knowing something about the
> format of the file. Those char[] members you wrote to the file, might
> they have tab characters in them?
>[/color]
The values which the char[] members hold onto are just words like,
"The quick brown fox jumped over the lazy dog" -- or whatever words
may be found in a government project. :-) The only whitespace
permissable is a blank. Between the struct members I insert a tab
delimiter for later parsing (see MY_MACRO_FORMAT above).[color=blue][color=green]
> >
> > Now the problem ...
> >
> > Stepping through the code in the debugger as values are written to the
> > vector, I see that the values for aStruct.thirdMember are always
> > garbage unless it contains 15 or less characters.
> >
> > BTW, the values always look good in the file to which I have written,
> > regardless of the number of characters for thirdMember. (I confirm
> > this with a text editor.)
> >
> > Please offer a solution where I can still take a C++ approach (instead
> > of C) as that is my preference, while not changing the legacy code
> > (namely, the struct above).[/color]
>
> Your problem does not appear to have anything to do with "mixing C and
> C++."
>[/color]
The reason I thought it may have to do with the mixing of languages is
that I write to the file with C and read the file with C++ where:

1)The only problem-child is the thirdMember, the first and second
members never take in garbage values and the only difference is the
size of the arrays in their definition, i.e., char firstMember[16] and
char secondMember[16] versus char thirdMember[96]. AND ...

2)The problem seems to have something to do with the "magical"
number 16, because if the thirdMember has < 16 characters then it
takes no garbage from the stream and the values look good.
[color=blue]
> There is nothing obviously wrong here (other than the
> '&filename[0]' thing). Try posting a complete, minimal program that
> demonstrates the problem, as well as some input to test it with.
>
> -Kevin[/color]

I started rewriting a minimal program but found it more involved than
expected; partly because of the presence of FOX, partly because I need
to change names and data for security reasons, and partly because of
the overarching functionality which crosses over a few different
classes. I haven't given-up on this yet and it may be a good approach
for troubleshooting anyway. But I thought I should go ahead and
respond to your post with the hope of presenting my problem more
clearly.

Thanks for all of your help,
Keith
Kevin Goodsell
Guest
 
Posts: n/a
#7: Jul 19 '05

re: Problem: writing to a file with C and reading with C++


Keith Dewell wrote:
[color=blue]
> I started rewriting a minimal program but found it more involved than
> expected;[/color]

Well, I did write a minimal program based on what you posted:

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>

using namespace std;

typedef struct {
char firstMember[16];
char secondMember[16];
char thirdMember[96];
unsigned long count;
} my_Struct_T;


#define MY_MACRO_FORMAT \
"%-12.12s\t%-8.8s\t%6d\t%-56.56s\t", \
aStruct.firstMember,aStruct.secondMember,aStruct.c ount,aStruct.thirdMember


int main()
{
FILE *fp = fopen("test.txt", "w");
if (fp == 0)
{
cerr << "could not open test.txt" << endl;
return 0;
}

my_Struct_T aStruct = {"first", "second",
"third is very very very very loooooonnnnnng", 24};
if (fp) fprintf(fp, MY_MACRO_FORMAT);

fclose(fp);

ifstream inputFileStream("test.txt");

std::vector<std::string> dataFromFile;
std::string aString;

while(std::getline(inputFileStream, aString, '\t'))
dataFromFile.push_back(aString);

return 0;
}


This works exactly as expected. I also noticed a few more errors in your
code while making this:

#define MY_MACRO_FORMAT \
"%-12.12s\t%-8.8s\t%6d\t%-56.56s\t", \
aStruct.firstMember,aStruct.secondMember,aStruct.c ount,Struct.thirdMember
^^^^^^

'Struct.thirdMember' should presumably be 'aStruct.thirdMember'.

And here:

std::ifstream inputFileStream(&filename[0], std::ios::in);

while(std::getline(inputFileStream[0], aString, '\t'))
dataFromFile.push_back(aString);

'inputFileStream[0]' should presumably NOT have the '[0]'.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Keith Dewell
Guest
 
Posts: n/a
#8: Jul 19 '05

re: Problem: writing to a file with C and reading with C++


Julián Albo <JULIANALBO@terra.es> wrote in message news:<3F730DC7.DFCD868B@terra.es>...[color=blue]
> Keith Dewell escribi :
>[color=green]
> > The other members of the struct show good data in the debugger, only
> > thirdMember shows garbage. This is why I believe this is an I/O
> > problem since the data looks good in the file I am reading and this is
> > the only variable where I see garbage; all the other members of the
> > struct show good data in the debugger as they come into the vector.[/color]
>
> Forget the debugger for one moment, and check the chars indvidually in
> the program, then you will know if it is a problem with the debugger or
> not.
>
> If it is a program with the debugger ask in a windows programming group,
> debuggers and compiler specific things are off-topic here.
>
> Regards.[/color]

Julián,

You were right(!), the problem was related to the debugger and also to
std::string. Here is a quote from Thore B. Karlsen on another thread
dated 2003-01-03 07:24:05 PST:

"The string class in VC++ 7.0 has a short string optimization for
strings of 16 characters or less. Anything with this length is stored
in a small buffer in the string object. For longer strings, memory is
allocated. What you're seeing is probably just the internal buffer."

Hence the "magic" number 16 I was encountering. BTW, Mr. Karlsen has
provided this solution for at least 3 different posters. And though
debuggers are off-topic I thought I should post this here just so
everyone can see the resolution to my problem.

Thanks Julián (and Kevin) for your help!

Regards,
Keith
Closed Thread