All member variables contain same value
-
:confused:I am using Visual C++ 6.0. I have an MFC Dialog based application. I have an class derived from CDialog called CIntrument that has edit controls. Each edit control has a unique IDD_EDIT identifier and have unique variables defined as Value CString. In a different CDialog box I instantiate an object of type 'CInstrument Inst'. I then use fscanf() to read text from a file into the member variables Inst.m_var_a, Inst.m_var_b, Inst.m_var_c and others. As each item of text is read ALL the member variables change to the value that was just read. I have verified this while stepping through the code one line at a time. I am very confused as to why variables with completely different names would be modified in this fashion. Thanks Buck
-
:confused:I am using Visual C++ 6.0. I have an MFC Dialog based application. I have an class derived from CDialog called CIntrument that has edit controls. Each edit control has a unique IDD_EDIT identifier and have unique variables defined as Value CString. In a different CDialog box I instantiate an object of type 'CInstrument Inst'. I then use fscanf() to read text from a file into the member variables Inst.m_var_a, Inst.m_var_b, Inst.m_var_c and others. As each item of text is read ALL the member variables change to the value that was just read. I have verified this while stepping through the code one line at a time. I am very confused as to why variables with completely different names would be modified in this fashion. Thanks Buck
Open the resource.h and the .rc file using the text editor and confirm that each edit control really does have a unique ID and that that ID is really a unique value. Next, check DoDataExchange and verify that the controls and the member variables are being assigned correctly. Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
-
:confused:I am using Visual C++ 6.0. I have an MFC Dialog based application. I have an class derived from CDialog called CIntrument that has edit controls. Each edit control has a unique IDD_EDIT identifier and have unique variables defined as Value CString. In a different CDialog box I instantiate an object of type 'CInstrument Inst'. I then use fscanf() to read text from a file into the member variables Inst.m_var_a, Inst.m_var_b, Inst.m_var_c and others. As each item of text is read ALL the member variables change to the value that was just read. I have verified this while stepping through the code one line at a time. I am very confused as to why variables with completely different names would be modified in this fashion. Thanks Buck
-
:confused:I am using Visual C++ 6.0. I have an MFC Dialog based application. I have an class derived from CDialog called CIntrument that has edit controls. Each edit control has a unique IDD_EDIT identifier and have unique variables defined as Value CString. In a different CDialog box I instantiate an object of type 'CInstrument Inst'. I then use fscanf() to read text from a file into the member variables Inst.m_var_a, Inst.m_var_b, Inst.m_var_c and others. As each item of text is read ALL the member variables change to the value that was just read. I have verified this while stepping through the code one line at a time. I am very confused as to why variables with completely different names would be modified in this fashion. Thanks Buck
What does the
fscanf()
statement look like?
"Let us be thankful for the fools. But for them the rest of us could not succeed." - Mark Twain
-
Open the resource.h and the .rc file using the text editor and confirm that each edit control really does have a unique ID and that that ID is really a unique value. Next, check DoDataExchange and verify that the controls and the member variables are being assigned correctly. Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
-
Darn, then I'm at a loss without looking at the source. Could it have to do with how fscanf() is being used? Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
-
Here are the two header and two cpp files. The code that is causing me problems is in the ListOfInstrumentsDlg::OnInitDialog() function at the bottom of this posting. // Instrument.h : header file // ///////////////////////////////////////////////////////////////////////////// // CInstrument dialog class CInstrument : public CDialog { // Construction public: CInstrument(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CInstrument) enum { IDD = IDD_DIALOG_INSTRUMENT }; CString m_GPIB; CString m_Name; CString m_Type; CString m_Channels; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CInstrument) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CInstrument) // NOTE: the ClassWizard will add member functions here //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_INSTRUMENT_H__E23BF332_8005_4295_B743_DDC7DC952923__INCLUDED_) ******************************************************** ******************************************************** // Instrument.cpp : implementation file // #include "stdafx.h" #include "ListOfInstruments.h" #include "Instrument.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CInstrument dialog CInstrument::CInstrument(CWnd* pParent /*=NULL*/) : CDialog(CInstrument::IDD, pParent) { //{{AFX_DATA_INIT(CInstrument) m_GPIB = _T(""); m_Name = _T(""); m_Type = _T(""); m_Channels = _T(""); //}}AFX_DATA_INIT } void CInstrument::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CInstrument) DDX_Text(pDX, IDC_EDIT_GPIB, m_GPIB); DDX_Text(pDX, IDC_EDIT_NAME, m_Name); DDX_Text(pDX, IDC_EDIT_TYPE, m_Type); DDX_Text(pDX, IDC_EDIT_CHANNELS, m_Channels); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CInstrument, CDialog) //{{AFX_MSG_MAP(CInstrument) // NOTE: the ClassWizard will add message map macros here //}}AFX_MSG_MAP END_MESSAGE_MAP() ******************************************************** ******************************************************** // // ListOfInstrumentsDlg
-
What does the
fscanf()
statement look like?
"Let us be thankful for the fools. But for them the rest of us could not succeed." - Mark Twain
Here are the two header and two cpp files. The code that is causing me problems is in the ListOfInstrumentsDlg::OnInitDialog() function. // Instrument.h : header file // ///////////////////////////////////////////////////////////////////////////// // CInstrument dialog class CInstrument : public CDialog { // Construction public: CInstrument(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CInstrument) enum { IDD = IDD_DIALOG_INSTRUMENT }; CString m_GPIB; CString m_Name; CString m_Type; CString m_Channels; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CInstrument) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CInstrument) // NOTE: the ClassWizard will add member functions here //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_INSTRUMENT_H__E23BF332_8005_4295_B743_DDC7DC952923__INCLUDED_) ******************************************************** ******************************************************** // Instrument.cpp : implementation file // #include "stdafx.h" #include "ListOfInstruments.h" #include "Instrument.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CInstrument dialog CInstrument::CInstrument(CWnd* pParent /*=NULL*/) : CDialog(CInstrument::IDD, pParent) { //{{AFX_DATA_INIT(CInstrument) m_GPIB = _T(""); m_Name = _T(""); m_Type = _T(""); m_Channels = _T(""); //}}AFX_DATA_INIT } void CInstrument::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CInstrument) DDX_Text(pDX, IDC_EDIT_GPIB, m_GPIB); DDX_Text(pDX, IDC_EDIT_NAME, m_Name); DDX_Text(pDX, IDC_EDIT_TYPE, m_Type); DDX_Text(pDX, IDC_EDIT_CHANNELS, m_Channels); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CInstrument, CDialog) //{{AFX_MSG_MAP(CInstrument) // NOTE: the ClassWizard will add message map macros here //}}AFX_MSG_MAP END_MESSAGE_MAP() ******************************************************** ******************************************************** // // ListOfInstrumentsDlg.h header file #include "In
-
Darn, then I'm at a loss without looking at the source. Could it have to do with how fscanf() is being used? Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
Here are the two header and two cpp files. The code that is causing me problems is in the ListOfInstrumentsDlg::OnInitDialog() function at the bottom of this posting. // Instrument.h : header file // ///////////////////////////////////////////////////////////////////////////// // CInstrument dialog class CInstrument : public CDialog { // Construction public: CInstrument(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CInstrument) enum { IDD = IDD_DIALOG_INSTRUMENT }; CString m_GPIB; CString m_Name; CString m_Type; CString m_Channels; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CInstrument) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CInstrument) // NOTE: the ClassWizard will add member functions here //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_INSTRUMENT_H__E23BF332_8005_4295_B743_DDC7DC952923__INCLUDED_) ******************************************************** ******************************************************** // Instrument.cpp : implementation file // #include "stdafx.h" #include "ListOfInstruments.h" #include "Instrument.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CInstrument dialog CInstrument::CInstrument(CWnd* pParent /*=NULL*/) : CDialog(CInstrument::IDD, pParent) { //{{AFX_DATA_INIT(CInstrument) m_GPIB = _T(""); m_Name = _T(""); m_Type = _T(""); m_Channels = _T(""); //}}AFX_DATA_INIT } void CInstrument::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CInstrument) DDX_Text(pDX, IDC_EDIT_GPIB, m_GPIB); DDX_Text(pDX, IDC_EDIT_NAME, m_Name); DDX_Text(pDX, IDC_EDIT_TYPE, m_Type); DDX_Text(pDX, IDC_EDIT_CHANNELS, m_Channels); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CInstrument, CDialog) //{{AFX_MSG_MAP(CInstrument) // NOTE: the ClassWizard will add message map macros here //}}AFX_MSG_MAP END_MESSAGE_MAP() ******************************************************** ******************************************************** // // ListOfInstrumentsDlg
-
Here are the two header and two cpp files. The code that is causing me problems is in the ListOfInstrumentsDlg::OnInitDialog() function at the bottom of this posting. // Instrument.h : header file // ///////////////////////////////////////////////////////////////////////////// // CInstrument dialog class CInstrument : public CDialog { // Construction public: CInstrument(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CInstrument) enum { IDD = IDD_DIALOG_INSTRUMENT }; CString m_GPIB; CString m_Name; CString m_Type; CString m_Channels; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CInstrument) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CInstrument) // NOTE: the ClassWizard will add member functions here //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_INSTRUMENT_H__E23BF332_8005_4295_B743_DDC7DC952923__INCLUDED_) ******************************************************** ******************************************************** // Instrument.cpp : implementation file // #include "stdafx.h" #include "ListOfInstruments.h" #include "Instrument.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CInstrument dialog CInstrument::CInstrument(CWnd* pParent /*=NULL*/) : CDialog(CInstrument::IDD, pParent) { //{{AFX_DATA_INIT(CInstrument) m_GPIB = _T(""); m_Name = _T(""); m_Type = _T(""); m_Channels = _T(""); //}}AFX_DATA_INIT } void CInstrument::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CInstrument) DDX_Text(pDX, IDC_EDIT_GPIB, m_GPIB); DDX_Text(pDX, IDC_EDIT_NAME, m_Name); DDX_Text(pDX, IDC_EDIT_TYPE, m_Type); DDX_Text(pDX, IDC_EDIT_CHANNELS, m_Channels); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CInstrument, CDialog) //{{AFX_MSG_MAP(CInstrument) // NOTE: the ClassWizard will add message map macros here //}}AFX_MSG_MAP END_MESSAGE_MAP() ******************************************************** ******************************************************** // // ListOfInstrumentsDlg
Of immediate concern, and I think the ultimate cause, is that you are using the CString variables directly, without getting the buffers. This is overwriting the null string the CString variables point to by default. You should do:
fscanf(infile, "%s", Inst.m_Type.GetBuffer(32)); Inst.m_Type.ReleaseBuffer();
This is rather unsafe since it assumes it will read only 32 characters. With VS 2007, you could do:fscanf_s(infile, "%s", Inst.m_Type.GetBuffer(32), 32); Inst.m_Type.ReleaseBuffer();
If you know they are numbers, I'd useint
s rather than CStrings and change the fscanf to:fscanf(infile, "%d", &Inst.m_Type);
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke -- modified at 17:14 Wednesday 22nd February, 2006 -
Of immediate concern, and I think the ultimate cause, is that you are using the CString variables directly, without getting the buffers. This is overwriting the null string the CString variables point to by default. You should do:
fscanf(infile, "%s", Inst.m_Type.GetBuffer(32)); Inst.m_Type.ReleaseBuffer();
This is rather unsafe since it assumes it will read only 32 characters. With VS 2007, you could do:fscanf_s(infile, "%s", Inst.m_Type.GetBuffer(32), 32); Inst.m_Type.ReleaseBuffer();
If you know they are numbers, I'd useint
s rather than CStrings and change the fscanf to:fscanf(infile, "%d", &Inst.m_Type);
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke -- modified at 17:14 Wednesday 22nd February, 2006Thanks, Because my file is comma delimited with variable length fields, some with white space in them I used the approach below. Works great! Buck CString in_buffer; char buffer[32]; FILE* infile; char* config_file = "Config.txt"; infile = fopen(config_file, "r"); int end_of_file = 0; CInstrument Inst; // Here is where the input read from the Config.txt file and stored in the respective variables. while (!end_of_file) { fscanf(infile, "%[^,]", &buffer); in_buffer.Format("%s", &buffer); Inst.m_Type = in_buffer; fscanf(infile, "%[,]", &buffer); fscanf(infile, "%[^,]", &buffer); in_buffer.Format("%s", &buffer); Inst.m_Name = in_buffer; fscanf(infile, "%[,]", &buffer); fscanf(infile, "%[^,]", &buffer); in_buffer.Format("%s", &buffer); Inst.m_GPIB = in_buffer; fscanf(infile, "%[,]", &buffer); fscanf(infile, "%[^\n]", &buffer); in_buffer.Format("%s", &buffer); Inst.m_Channels = in_buffer; fscanf(infile, "%[\n]", &buffer); m_ListInstruments.AddString(Inst.m_Name); if (feof(infile)) end_of_file = 1; } Buck
-
Here are the two header and two cpp files. The code that is causing me problems is in the ListOfInstrumentsDlg::OnInitDialog() function. // Instrument.h : header file // ///////////////////////////////////////////////////////////////////////////// // CInstrument dialog class CInstrument : public CDialog { // Construction public: CInstrument(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CInstrument) enum { IDD = IDD_DIALOG_INSTRUMENT }; CString m_GPIB; CString m_Name; CString m_Type; CString m_Channels; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CInstrument) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CInstrument) // NOTE: the ClassWizard will add member functions here //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_INSTRUMENT_H__E23BF332_8005_4295_B743_DDC7DC952923__INCLUDED_) ******************************************************** ******************************************************** // Instrument.cpp : implementation file // #include "stdafx.h" #include "ListOfInstruments.h" #include "Instrument.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CInstrument dialog CInstrument::CInstrument(CWnd* pParent /*=NULL*/) : CDialog(CInstrument::IDD, pParent) { //{{AFX_DATA_INIT(CInstrument) m_GPIB = _T(""); m_Name = _T(""); m_Type = _T(""); m_Channels = _T(""); //}}AFX_DATA_INIT } void CInstrument::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CInstrument) DDX_Text(pDX, IDC_EDIT_GPIB, m_GPIB); DDX_Text(pDX, IDC_EDIT_NAME, m_Name); DDX_Text(pDX, IDC_EDIT_TYPE, m_Type); DDX_Text(pDX, IDC_EDIT_CHANNELS, m_Channels); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CInstrument, CDialog) //{{AFX_MSG_MAP(CInstrument) // NOTE: the ClassWizard will add message map macros here //}}AFX_MSG_MAP END_MESSAGE_MAP() ******************************************************** ******************************************************** // // ListOfInstrumentsDlg.h header file #include "In
99% of this code is unnecessary to describe your problem. In the future, please try to trim away as much as you can before posting. That goes a long way in obtaining help.
BuckBrown wrote:
FILE* infile; char* config_file = "Config.txt";
Just curious, but why are you using
FILE*
andchar*
with MFC? It's syntactically correct, but not necessary.BuckBrown wrote:
fscanf(infile, "%[^,]", Inst.m_Type);
The first thing to do is separate
CString
fromfscanf()
. While they technically can be made to work together, it's messy and not worth the trouble.char szText[128];
fscanf(infile, "%[^,]", szText);
Inst.m_Type = szText;BuckBrown wrote:
fscanf(infile, "%[,]", &m_Comma);
This will never work as
m_Comma
is a pointer that does not point to a valid memory address. To eat the comma, just add it to thefscanf()
statement:fscanf(infile, "%[^,],", szText);
"Let us be thankful for the fools. But for them the rest of us could not succeed." - Mark Twain
-
Thanks, Because my file is comma delimited with variable length fields, some with white space in them I used the approach below. Works great! Buck CString in_buffer; char buffer[32]; FILE* infile; char* config_file = "Config.txt"; infile = fopen(config_file, "r"); int end_of_file = 0; CInstrument Inst; // Here is where the input read from the Config.txt file and stored in the respective variables. while (!end_of_file) { fscanf(infile, "%[^,]", &buffer); in_buffer.Format("%s", &buffer); Inst.m_Type = in_buffer; fscanf(infile, "%[,]", &buffer); fscanf(infile, "%[^,]", &buffer); in_buffer.Format("%s", &buffer); Inst.m_Name = in_buffer; fscanf(infile, "%[,]", &buffer); fscanf(infile, "%[^,]", &buffer); in_buffer.Format("%s", &buffer); Inst.m_GPIB = in_buffer; fscanf(infile, "%[,]", &buffer); fscanf(infile, "%[^\n]", &buffer); in_buffer.Format("%s", &buffer); Inst.m_Channels = in_buffer; fscanf(infile, "%[\n]", &buffer); m_ListInstruments.AddString(Inst.m_Name); if (feof(infile)) end_of_file = 1; } Buck
Maybe you could save yourself some duplicate effort. Could you replace this:
fscanf(infile, "%[,]", &buffer); fscanf(infile, "%[^\n]", &buffer); in_buffer.Format("%s", &buffer); Inst.m_Channels = in_buffer;
with this, for example:fscanf(infile, "%[,]", &buffer); fscanf(infile, "%[^\n]", &buffer); Inst.m_Channels.Format("%s", &buffer);
That is one less string copy and memory adjustment. You would not need or use the in_buffer at all. People that start writing code immediately are programmers (or hackers), people that ask questions first are Software Engineers - Graham Shanks