|
From: Kenneth P. R. <kpr...@op...> - 2004-01-23 06:00:36
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
<small><font face="Helvetica, Arial, sans-serif">I finally decided to
teach myself C++ from "Core C++: A Software Engineering Approach"
(2000) by Victor Shtern, "Rescued by C++" 3rd Ed. by Kris Jamsa (which
was a Borland Turbo C++ Lite book, and now mostly rely on C/C++
Programmer's Reference 2nd Ed. by Herbert Schildt. And, I finally had
a real-world application to write a program. Here's the code excerpt
that has me baffled.<br>
<br>
for (y=1; y<=i; y++);<br>
if (Groupset[y].substr(0,3) == Day1.substr)x*3-3,3))<br>
{<br>
TotDay[x-1]++;<br>
while (MtgCode0 == "P") MtgType=10;<br>
while (MtgCode0 == "L") MtgType=11;<br>
while (MtgCode0 == "W") MtgType=12;<br>
<br>
switch (MtgType)<br>
{<br>
case '10': TotP++; break;<br>
case '11': TotL++; break;<br>
case '12': TotW++; break;<br>
default: TotOther++;<br>
} // terminates Switch<br>
<br>
} // terminates if<br>
}; // terminates for<br>
<br>
Up to this point, the program runs fine, but it hangs when it hits
"while (MtgCode0 == "W") MtgType=12. In Debug, I set this line and the
"switch (MtgType) line as checkpoints. When the "while" stmt is
encountered, it turns blue in Debug, and will not go past this point.
Debug will not continue; the cursor stays on this line. Note that the
Debug screen is not frozen -- I can still set checkpoints, move the
cursor, etc. But it will not continue after this point.<br>
<br>
What's going on here?<br>
<br>
Thx, Ken<br>
</font></small>
</body>
</html>
|
|
From: Doug M. <dou...@al...> - 2004-01-23 07:14:44
|
Hi Ken,
It's hard to tell what's going on without any variable declarations or
code comments.
Two things are interesting about your code.
First the hang you are seeing. Do you know that the construct
while (MtgCode0 == "W") MtgType=12;
repeats the assignment 'MtgType=12' over and over, as long as the
expression 'MtgCode0 == "W"' remains true? This line will do one of two
things. It will drop through without doing the assignment if MtgCode0
!= "W". Or, if MtgCode0 == "W", it will hang.
You probably wanted straight-through conditionals rather than loops,
something more like:
switch ((int)*(char *)MtgCode0) {
case 'P':
MtgType=10; TotP++; break;
case 'L':
MtgType=11; TotL++; break;
case 'W':
MtgType=12; TotW++; break;
default: TotOther++;
}
However, if I understand your intent, there may be another problem
lurking in your code snippet. I hope you realize that in the expression
MtgCode0 == "W"
you are checking for equality of the value contained in the variable
MtgCode0 with the _address_ of the literal string "W". This code is not
performing a string match! In C and C++, the runtime value of a quoted
string literal (e.g., "W") is the memory address of its first character
- not the char's value.
But, you may say, I've used code like this before, and the comparison
does work when I've assigned "W" to MtgCode0!
Well, yes, it has happened to work, but only because of a fact about how
the compilers generate code.
I'm guessing that prior to reaching this part of the program, another
part of the code assigned the value "W" to MtgCode0. Right? When you
compiled the program, the compiler noticed that you were using the
string literal "W" in more than one place, and its codegen combined the
first "W" (the one you assigned to MtgCode0) and the second "W" (the one
in the equality test) into the same object. Compilers like to economize.
So, when you earlier assigned "W" to MtgCode0, you were really assigning
its address to MtgCode0. And later, when you checked MtgCode0 against
"W", you were really testing the _address_ contained in MtgCode0 against
the _address_ of [the same code object representing] "W".
This works as long as the compiler likes to economize with its code
generation of string literals, AND is able to do so. That's a risky
assumption to make. Suppose you assign the "W" in one subprogram in one
file, let's call it doubleyoo1.cpp, and test equality with "W" in a
second subprogram in a different file, doubleyoo2.cpp. Suppose further
that you compiled the two at separate times and then linked them.
Dollars to donuts, there will be two copies of "W" in the resulting
binary, and the equality test will fail.
You'd be safer using the single-quoted 'W' (an int value containing the
ASCII code for doubleyoo) rather than "W" (the address of a
compiler-generated, zero-terminated, length-two C string containing the
ASCII code for doubleyoo). If you look back, you'll see that is what I
have done in my suggested replacement for your "while" and "switch" blocks.
Hope this helps,
Doug
> I finally decided to teach myself C++ from "Core C++: A Software Engineering Approach" (2000) by Victor Shtern, "Rescued by C++" 3rd Ed. by Kris Jamsa (which was a Borland Turbo C++ Lite book, and now mostly rely on C/C++ Programmer's Reference 2nd Ed. by Herbert Schildt. And, I finally had a real-world application to write a program. Here's the code excerpt that has me baffled.
>
> for (y=1; y<=i; y++);
> if (Groupset[y].substr(0,3) == Day1.substr)x*3-3,3))
> {
> TotDay[x-1]++;
> while (MtgCode0 == "P") MtgType=10;
> while (MtgCode0 == "L") MtgType=11;
> while (MtgCode0 == "W") MtgType=12;
>
> switch (MtgType)
> {
> case '10': TotP++; break;
> case '11': TotL++; break;
> case '12': TotW++; break;
> default: TotOther++;
> } // terminates Switch
>
> } // terminates if
> }; // terminates for
>
> Up to this point, the program runs fine, but it hangs when it hits "while (MtgCode0 == "W") MtgType=12. In Debug, I set this line and the "switch (MtgType) line as checkpoints. When the "while" stmt is encountered, it turns blue in Debug, and will not go past this point. Debug will not continue; the cursor stays on this line. Note that the Debug screen is not frozen -- I can still set checkpoints, move the cursor, etc. But it will not continue after this point.
>
> What's going on here?
>
> Thx, Ken
> ------------------------------------------------------- The SF.Net email is sponsored by EclipseCon 2004 Premiere Conference on Open Tools Development and Integration See the breadth of Eclipse activity. February 3-5 in Anaheim, CA. http://www.eclipsecon.org/osdn _______________________________________________ Dev-cpp-users mailing list Dev...@li... TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
|
|
From: Kenneth P. R. <kpr...@op...> - 2004-01-23 11:03:41
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
<small><font face="Helvetica, Arial, sans-serif">Hi Doug,<br>
<br>
Thanks for such a thorough response.<br>
<br>
Actually, the root of my problem(s) is char vs. string. The problem
starts right there, because I cannot use string functions on a char
array. Below, I have gotten to the heart of my lack of understanding.
That commented-out "string inbufstr" is there because up to now, I have
been coding that "inbufstr=inbuf" statement to convert the char array
to a string. Then, I get access to the string manipulation functions.<br>
<br>
**************************************************************************************<br>
#include <fstream><br>
#include <iostream><br>
#include <string><br>
using namespace std;<br>
<br>
int main(void)<br>
{<br>
int i,TotRecs;<br>
char inbuf[80];<br>
// string inbufstr; <br>
<br>
ifstream MtgRec("Q:\\C++\\AAMtgs.txt");<br>
ofstream AnalRec("Q:\\C++\\Analysis.txt");<br>
ofstream ZipRec("Q:\\C++\\Towns.txt"); <br>
if (MtgRec.fail()) {cout << "Cannot open file" << endl;}<br>
<br>
i=-1; // 1st iteration is 0 (for 1st subscript)<br>
<br>
while (! MtgRec.eof())<br>
{<br>
MtgRec.getline(inbuf,80);<br>
i++;<br>
TotRecs++;<br>
}<br>
// inbufstr=inbuf;<br>
if (inbuf.substr(0,3) == 'ZIP') inbuf.erase(0,3); // This
stmt yields error "request for member 'substr' in 'inbuf', which is of
non-aggregate type 'char[80]'"<br>
system("pause");<br>
}<br>
*************************************************************************************<br>
<br>
This is where my flip-flopping around and mixing strings and chars
begins. <br>
<br>
I am sure the answer to this is so simple that I will be astonished
that I missed it. But I'm a real quick study, so go ahead, tell me the
way out of this.<br>
<br>
TIA,<br>
Ken</font></small><br>
</body>
</html>
|
|
From: Per W. <pw...@ia...> - 2004-01-23 11:57:27
|
Since char xx[] is a native type, there are no built-in functions
available for character arrays. If you want to perform any operations, you
must call the global functions declared in string.h.
// Compare first 3 characters in array
if (!strncmp(inbuf,"ZIP",3))
// Locate a substring anywhere in the character array
if (strstr(inbuf,"ZIP"))
/Per W
On Fri, 23 Jan 2004, Kenneth P. Ruppel wrote:
> Hi Doug,
>
> Thanks for such a thorough response.
>
> Actually, the root of my problem(s) is char vs. string.=A0 The problem st=
arts right there, because I cannot use string functions on a char array.=A0
> Below, I have gotten to the heart of my lack of understanding.=A0 That co=
mmented-out "string inbufstr" is there because up to now, I have been
> coding that "inbufstr=3Dinbuf" statement to convert the char array to a s=
tring.=A0 Then, I get access to the string manipulation functions.
>
> *************************************************************************=
*************
> #include <fstream>
> #include <iostream>
> #include <string>
> using namespace std;
>
> int main(void)
> {
> =A0=A0=A0 int i,TotRecs;
> =A0=A0=A0 char inbuf[80];
> // =A0=A0 string inbufstr;=A0=A0
> =A0=A0=A0
> =A0=A0=A0 ifstream MtgRec("Q:\\C++\\AAMtgs.txt");
> =A0=A0=A0 ofstream AnalRec("Q:\\C++\\Analysis.txt");
> =A0=A0=A0 ofstream ZipRec("Q:\\C++\\Towns.txt");=A0=A0=A0
> =A0=A0=A0 if (MtgRec.fail()) {cout << "Cannot open file" << endl;}
>
> =A0=A0=A0 i=3D-1;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 // 1st iteration is 0 =
(for 1st subscript)
>
> =A0=A0=A0 while (! MtgRec.eof())
> =A0=A0=A0 {
> =A0=A0=A0 MtgRec.getline(inbuf,80);
> =A0=A0=A0 i++;
> =A0=A0=A0 TotRecs++;
> =A0=A0=A0 }
> // =A0=A0 inbufstr=3Dinbuf;
> =A0=A0=A0 if (inbuf.substr(0,3) =3D=3D 'ZIP')=A0 inbuf.erase(0,3);=A0=A0 =
=A0=A0 // This stmt yields error "request for member 'substr' in 'inbuf', w=
hich is of
> non-aggregate type 'char[80]'"
> system("pause");
> =A0=A0=A0 }
> *************************************************************************=
************
>
> This is where my flip-flopping around and mixing strings and chars begins=
=2E=A0
>
> I am sure the answer to this is so simple that I will be astonished that =
I missed it.=A0 But I'm a real quick study, so go ahead, tell me the way
> out of this.
>
> TIA,
> Ken
> ------------------------------------------------------- The SF.Net email =
is sponsored by EclipseCon 2004 Premiere Conference on Open Tools
> Development and Integration See the breadth of Eclipse activity. February=
3-5 in Anaheim, CA. http://www.eclipsecon.org/osdn
> _______________________________________________ Dev-cpp-users mailing lis=
t Dev...@li... TO UNSUBSCRIBE:
> http://www23.brinkster.com/noicys/devcpp/ub.htm https://lists.sourceforge=
=2Enet/lists/listinfo/dev-cpp-users
>
|
|
From: Maya <Esc...@ne...> - 2004-01-26 03:54:58
|
You know what I would do? I would solve the whole thing by not using the
char array, just use the std::string.
The program is a C++ program, and as a C++ programmer you have to master
the object oriented paradigm. Forger about char, that's a more 'C' kind
of style!
Have good one!!
kpr...@op... wrote:
> Hi Doug,
>
> Thanks for such a thorough response.
>
> Actually, the root of my problem(s) is char vs. string. The problem
> starts right there, because I cannot use string functions on a char
> array. Below, I have gotten to the heart of my lack of
> understanding. That commented-out "string inbufstr" is there because
> up to now, I have been coding that "inbufstr=inbuf" statement to
> convert the char array to a string. Then, I get access to the string
> manipulation functions.
>
> **************************************************************************************
> #include <fstream>
> #include <iostream>
> #include <string>
> using namespace std;
>
> int main(void)
> {
> int i,TotRecs;
> char inbuf[80];
> // string inbufstr;
>
> ifstream MtgRec("Q:\\C++\\AAMtgs.txt");
> ofstream AnalRec("Q:\\C++\\Analysis.txt");
> ofstream ZipRec("Q:\\C++\\Towns.txt");
> if (MtgRec.fail()) {cout << "Cannot open file" << endl;}
>
> i=-1; // 1st iteration is 0 (for 1st subscript)
>
> while (! MtgRec.eof())
> {
> MtgRec.getline(inbuf,80);
> i++;
> TotRecs++;
> }
> // inbufstr=inbuf;
> if (inbuf.substr(0,3) == 'ZIP') inbuf.erase(0,3); // This
> stmt yields error "request for member 'substr' in 'inbuf', which is of
> non-aggregate type 'char[80]'"
> system("pause");
> }
> *************************************************************************************
>
> This is where my flip-flopping around and mixing strings and chars
> begins.
>
> I am sure the answer to this is so simple that I will be astonished
> that I missed it. But I'm a real quick study, so go ahead, tell me
> the way out of this.
>
> TIA,
> Ken
> ------------------------------------------------------- The SF.Net
> email is sponsored by EclipseCon 2004 Premiere Conference on Open
> Tools Development and Integration See the breadth of Eclipse activity.
> February 3-5 in Anaheim, CA. http://www.eclipsecon.org/osdn
> _______________________________________________ Dev-cpp-users mailing
> list Dev...@li... TO UNSUBSCRIBE:
> http://www23.brinkster.com/noicys/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
--
FYI
http://www.astro.umd.edu/~marshall/abbrev.html
E-Mail Policy
http://www.vif.com/users/escalante/Email_Policy.html
* You cannot exercise your power to a point of humiliation.
- Jean Chretien
* The media's the most powerful entity on earth. They have the
power to make the innocent guilty and to make the guilty
innocent, and that's power.
- Malcom X
* "Innocent until proven guilty", no... not in Canada!!
|