The official C++ help thread
<div class="IPBDescription">For people who need help with their social lives</div>Okay, you heard it first here folks, I need help with c++.
Rather, I need help with a compiler. I'm using microsoft visual studio 2005 standard edition, compile configuration set to 'release' and 'win32', and I can about 50% of the time get a fully-operational .exe release from my compilation efforts. (The other 50% it doesn't seem to recognise cin.get() at the end of my code, but I can jiggle it until it works.)
However, I send the standalone .exe to my friend, and she gets:
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->Windows cannot access the specified device, path or file. You may not have the appropriate permissions to access the item.<!--QuoteEnd--></div><!--QuoteEEnd-->
I have no idea where to go with this, I'm using cprogramming.com to learn the basics of the syntax, but the compiler issues have left me confused and annoyed. If anybody had any experience with this and could suggest anything, that'd be great. I also have precompiled headers turned off.
People should also feel encouraged to ask their C++ related questions in here so I can come back to it again and again with my programming-related incompetence. Thanks.
Rather, I need help with a compiler. I'm using microsoft visual studio 2005 standard edition, compile configuration set to 'release' and 'win32', and I can about 50% of the time get a fully-operational .exe release from my compilation efforts. (The other 50% it doesn't seem to recognise cin.get() at the end of my code, but I can jiggle it until it works.)
However, I send the standalone .exe to my friend, and she gets:
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->Windows cannot access the specified device, path or file. You may not have the appropriate permissions to access the item.<!--QuoteEnd--></div><!--QuoteEEnd-->
I have no idea where to go with this, I'm using cprogramming.com to learn the basics of the syntax, but the compiler issues have left me confused and annoyed. If anybody had any experience with this and could suggest anything, that'd be great. I also have precompiled headers turned off.
People should also feel encouraged to ask their C++ related questions in here so I can come back to it again and again with my programming-related incompetence. Thanks.
Comments
Notepad(or another simple editor of your choosing) + GCC compiler
Dev-C++( <a href="http://www.bloodshed.net/devcpp.html" target="_blank">http://www.bloodshed.net/devcpp.html</a> ). It won't require you to use any DOS prompts(GCC will). Probably the best option.
Something else
you are making sure you're accessing the std namespace with regard to cin right?
<!--QuoteEnd--></div><!--QuoteEEnd-->
I was testing the random function and then I wanted to test the compile itself, so here is the code in full:
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->#include <iostream>
#include <time.h>
#include "stdafx.h"
using namespace std;
const int LOW = 5;
const int HIGH = 15;
int main()
{
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);
int roll = rand() % (HIGH - LOW + 1) + LOW;
int roll2 = rand() % (HIGH - LOW +1) + LOW;
int x = roll;
int y;
cout<< "I have a fun little program for you. Do what it says and you won't get hurt. \n\n";
cout<< "You must enter a number until x is equal to or over 300.\n";
while ( x < 300 ) {
cout<< "X is "<< x <<".\n";
cout<< "Please enter a number.\n";
cin>> y;
cout<< "You entered: "<< y <<".\n";
x = x + y;
}
cout<< "X is now: "<< x <<". That is over 300.\n";
cout<< "You win!\n";
cin.get();
}
<!--QuoteEnd--></div><!--QuoteEEnd-->
edit: just on a hunch, have you tried not using stdafx.h?
I've got a class which i've exported from a DLL. The class is as follows:
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->
class __declspec(dllexport) RtMidiIn : public RtMidi
{
public:
//! User callback function type definition.
typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData);
// ^ THIS MIGHT NEED TO BE EXPORTED
//! Default constructor.
/*!
An exception will be thrown if a MIDI system initialization error occurs.
*/
RtMidiIn();
//! If a MIDI connection is still open, it will be closed by the destructor.
~RtMidiIn();
//! Open a MIDI input connection.
/*!
An optional port number greater than 0 can be specified.
Otherwise, the default or first port found is opened.
*/
void openPort( unsigned int portNumber = 0 );
static void finish(int ignore); //added from qmidiin
std::vector<unsigned char> Getmidi(void); //fetches MIDI data, and little else
int Errorcheck (RtMidiIn& midiin); //new function for error checking
//! Create a virtual input port, with optional name, to allow software connections (OS X and ALSA only).
/*!
This function creates a virtual MIDI input port to which other
software applications can connect. This type of functionality
is currently only supported by the Macintosh OS-X and Linux ALSA
APIs (the function does nothing for the other APIs).
*/
void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) );
//! Set a callback function to be invoked for incoming MIDI messages.
/*!
The callback function will be called whenever an incoming MIDI
message is received. While not absolutely necessary, it is best
to set the callback function before opening a MIDI port to avoid
leaving some messages in the queue.
*/
void setCallback( RtMidiCallback callback, void *userData = 0 );
//! Cancel use of the current callback function (if one exists).
/*!
Subsequent incoming MIDI messages will be written to the queue
and can be retrieved with the \e getMessage function.
*/
void cancelCallback();
//! Close an open MIDI connection (if one exists).
void closePort( void );
//! Return the number of available MIDI input ports.
unsigned int getPortCount();
//! Return a string identifier for the specified MIDI input port number.
/*!
An exception is thrown if an invalid port specifier is provided.
*/
std::string getPortName( unsigned int portNumber = 0 );
//! Set the maximum number of MIDI messages to be saved in the queue.
/*!
If the queue size limit is reached, incoming messages will be
ignored. The default limit is 1024.
*/
void setQueueSizeLimit( unsigned int queueSize );
//! Specify whether certain MIDI message types should be queued or ignored during input.
/*!
By default, MIDI timing and active sensing messages are ignored
during message input because of their relative high data rates.
MIDI sysex messages are ignored by default as well. Variable
values of "true" imply that the respective message type will be
ignored.
*/
void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true );
//! Fill the user-provided vector with the data bytes for the next available MIDI message in the input queue and return the event delta-time in seconds.
/*!
This function returns immediately whether a new message is
available or not. A valid message is indicated by a non-zero
vector size. An exception is thrown if an error occurs during
message retrieval or an input connection was not previously
established.
*/
double getMessage( std::vector<unsigned char> *message );
// A MIDI structure used internally by the class to store incoming
// messages. Each message represents one and only one MIDI message.
struct MidiMessage { //COMMENTED OUT: Not sure what to do with this yet
std::vector<unsigned char> bytes;
double timeStamp;
// Default constructor.
MidiMessage()
:bytes(3), timeStamp(0.0) {}
};
// The RtMidiInData structure is used to pass private class data to
// the MIDI input handling function or thread.
__declspec(dllexport) struct RtMidiInData {
std::queue<MidiMessage> queue;
unsigned int queueLimit;
unsigned char ignoreFlags;
bool doInput;
bool firstMessage;
void *apiData;
bool usingCallback;
void *userCallback;
void *userData;
// Default constructor.
RtMidiInData()
: queueLimit(1024), ignoreFlags(7), doInput(false), firstMessage(true),
apiData(0), usingCallback(false), userCallback(0), userData(0) {}
};
private:
void initialize( void );
RtMidiInData inputData_;
};
<!--QuoteEnd--></div><!--QuoteEEnd-->
If I compile this as it is, I get this warning:
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->
n:\my documents\visual studio 2005\projects\midicapture\midicapture\rtmidi.h(189) : warning C4251: 'RtMidiIn::inputData_' : struct 'RtMidiIn::RtMidiInData' needs to have dll-interface to be used by clients of class 'RtMidiIn'<!--QuoteEnd--></div><!--QuoteEEnd-->
Which is strange, because if you notice I exported the entire class already. Surely it doesn't NEED exporting again? And sure enough, if I change the line to __declspec(dllexport) RtMidiInData inputData_; (or RtMidiInData __declspec(dllexport) inputData_; just in case that worked) I get an invalid storage class error.
So what the hell am I supposed to do? If I export again it it won't compile, if I don't export again it it crashes because it can't find itself.
I can't see anything wrong with that code that would cause an error message like that, so I'd also say it's a settings issue.
What does stdafx.h do? Is that a Visual Studio extention or is it your code? There aren't any identifiers in your code that aren't brought in only by other headers you've included.
Stylistically, it's better to use <!--fonto:Courier New--><span style="font-family:Courier New"><!--/fonto-->#include <ctime><!--fontc--></span><!--/fontc--> than <!--fonto:Courier New--><span style="font-family:Courier New"><!--/fonto-->#include <time.h><!--fontc--></span><!--/fontc-->. Using <ctime> means that the identifiers it brings in will stay in the <!--fonto:Courier New--><span style="font-family:Courier New"><!--/fonto-->std::<!--fontc--></span><!--/fontc--> namespace. time.h is for compatability with C, which doesn't have namespaces.
<!--quoteo(post=1588196:date=Dec 14 2006, 08:58 AM:name=Gwahir)--><div class='quotetop'>QUOTE(Gwahir @ Dec 14 2006, 08:58 AM) [snapback]1588196[/snapback]</div><div class='quotemain'><!--quotec-->
besides missing return 0; nothing jumps out at me. I haven't really used 2005 much, only the express version during short trip when I needed quick access to a compiler. So if it is a problem with the project settings, especially settings specific to 2005, I'm not much help.
edit: just on a hunch, have you tried not using stdafx.h?
<!--QuoteEnd--></div><!--QuoteEEnd-->
It's legal C++ to omit the return from <!--fonto:Courier New--><span style="font-family:Courier New"><!--/fonto-->main<!--fontc--></span><!--/fontc-->.
The compilation problem is.. unconfirmed. The situation is this:
The original person I sent it to reported that it would not work, and gave some permissions error.
The next two people I sent it to had visual studio installed, so if it's a library or std error, that won't help. It worked for those two.
The next two people I sent it to had weird personal computer problems that probably affected the outcome, so there's no way to use their results as evidence. It did not work for those two, for various different reasons.
Gwahir has told me that the version I'm running has an academic license though, so I'm going to use dev c++ to compile from now on, once I borrow a C++ book from the library.
Coming to think of C++, has anyone tried comiling the HL2 SDK with VC Express 2005? According to the developement notes it theoretically works, however still working on trying to resolve all the linking errors as I can't find a copy of VStudio 2k3(MS no longer releases it.) for modding. D: If anyone has successfully compiled it in any form with VCExpress 2k5 or VStudio 2k5 let me know. : X
<!--QuoteEnd--></div><!--QuoteEEnd-->
I didn't even get a notice about HL2 SDK coming out for it (Visual Studio 2005). I'm apart of that whole Developers thing that project is all oriented and I never got no notice about it. I was actually looking forward to seeing if it would make much of a difference for the HL mod community.
I guess I will have to take a look.
Thanks for the heads up on the ctime. The stdafx I can't remember what it does, I just remember getting weird errors when it isn't included. I think that was something to do with having precompiled headers turned on, though.
The compilation problem is.. unconfirmed. The situation is this:
The original person I sent it to reported that it would not work, and gave some permissions error.
The next two people I sent it to had visual studio installed, so if it's a library or std error, that won't help. It worked for those two.
The next two people I sent it to had weird personal computer problems that probably affected the outcome, so there's no way to use their results as evidence. It did not work for those two, for various different reasons.
Gwahir has told me that the version I'm running has an academic license though, so I'm going to use dev c++ to compile from now on, once I borrow a C++ book from the library.
<!--QuoteEnd--></div><!--QuoteEEnd-->
Create a new project make sure that after you set the project name and hit ok.
Go to application settings and set it to empty project. Other wise it includes that stdafx crap.
Then copy paste your code in while removing #include stdafx.
What stdafx is some extra stuff you dont need unless you know what it does.
Does anybody know a good tutorial for pointers? I've read 3 and I still don't quite understand their entire use. The three I've read were:
<a href="http://www.cprogramming.com/tutorial/lesson6.html" target="_blank">http://www.cprogramming.com/tutorial/lesson6.html</a>
<a href="http://www.boredzo.org/pointers/" target="_blank">http://www.boredzo.org/pointers/</a>
and <a href="http://www.cplusplus.com/doc/tutorial/pointers.html" target="_blank">http://www.cplusplus.com/doc/tutorial/pointers.html</a>
Although the last one is probably the best.
Your friend is not logged into her machine with an administrator account. Would be the most likely explanation.
Here is the code:
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->#include <string>
#include <iostream>
using namespace std;
int main()
{
string greeting1 = "Hows it going amigo la la la sup.\n"; // create a string of the text
string *myString = &greeting1; // create a pointer to the string
cout<< *myString <<endl; // output the de-referenced pointer, i.e text
int length = myString->length(); // creating integer "length" that finds the length of the pointer myString
cout<< length <<"\n" <<endl; // output the integer length
length = length + 1; // add '1' to the length of the string to account for null character
char greeting2[length]; // hopefully create a char of length found above
char *strcpy(char greeting2, const string *myString); // hopefully copy the de-referenced text in the pointer to greeting 2
cout<< greeting2 <<endl; // output greeting2
}<!--QuoteEnd--></div><!--QuoteEEnd-->
The problem is with the third last line, in my char greeting2[length]... well, sort of. When it was working before, the strcpy generates 0 to greeting2, so that might be a problem with my strcpy line, or with the general problem with variable array elements.
Null-terminated arrays of characters are C style strings. For general stringy stuff, C++ std::strings are much better.
[edit]on closer inspection...
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec--><u>char *</u>strcpy(char greeting2, const string *myString); <!--QuoteEnd--></div><!--QuoteEEnd-->
The underlined bit shouldn't be there; in this context it's meaningless. I'm not sure what you're trying to do with that.
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->char greeting2[length]; // hopefully create a char of length found above<!--QuoteEnd--></div><!--QuoteEEnd-->
This syntax for declaring arrays only works for fixed size arrays, and can be done if length is a constant (not a variable).
Arrays is a bit of a messy issue. They're very closely related to pointers. I don't know if you've done anything with allocating memory, but it's related to that.
The code you're after is
<!--fonto:Courier--><span style="font-family:Courier"><!--/fonto-->char* greeting = new char[length];<!--fontc--></span><!--/fontc-->
The "new" will allocate a contiguous block of characters <!--fonto:Courier--><span style="font-family:Courier"><!--/fonto-->length<!--fontc--></span><!--/fontc--> long, with the first element at *char. Memory allocated this way needs to be freed with a call like <!--fonto:Courier--><span style="font-family:Courier"><!--/fonto-->free greeting;<!--fontc--></span><!--/fontc-->
...that's a very, very brief and probably not helpful explanation (can't really concentrate at the moment; sorry), but should give you something of an idea of what to look for. Complicating the issue more is that C++ has classes that behave like arrays but do the job better (much like it has strings that behave like character arrays only better). It's important to learn and understand the C style arrays, but it's also important to learn to use the C++ ones in code in general. [/edit]
A string (that is, a C++ <!--fonto:courier--><span style="font-family:courier"><!--/fonto-->std::string<!--fontc--></span><!--/fontc-->, which is what you're using) isn't an array of characters - it's a class. Call the string.c_str() method to get an array-of-characters representation of a string, which you can use with the strcpy function.
Null-terminated arrays of characters are C style strings. For general stringy stuff, C++ std::strings are much better.
<!--QuoteEnd--></div><!--QuoteEEnd-->
Thanks. I just wanted to know a way to convert strings into c-style arrays because I've heard they're a lot faster than playing around with a whole lot of strings. I'm thinking of mucking around with a text-based game to practice C++ so I was wondering how much of an issue it really was.
Although... how am I supposed to create an array of variable size?
That said, since you're learning the language, it's still important to learn how to use arrays and C strings anyway, so getting practise with them is a good idea.
Anyway, yeah, I'm learning the language. I can imagine variably-sized arrays coming into handy in the future... do you know how to do them? I've been mucking around, trying to create one using pointers, but it's just not coming through. Any ideas?
True, I forgot how dangerous C++ could be if you aren't careful.
Anyway, yeah, I'm learning the language. I can imagine variably-sized arrays coming into handy in the future... do you know how to do them? I've been mucking around, trying to create one using pointers, but it's just not coming through. Any ideas?
<!--QuoteEnd--></div><!--QuoteEEnd-->
I edited my post as you were replying <img src="style_emoticons/<#EMO_DIR#>/smile-fix.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile-fix.gif" />. Um... I don't think my reply was all that coherent, though (I really need sleep).
Btw, <a href="http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.21" target="_blank">this</a> might be a useful source of information. The site is mostly intermediate to advanced stuff, but there might be useful stuff in the newbie section. There's also <a href="http://home.no.net/dubjai/win32cpptut/html/" target="_blank">this</a>, which I think is incomplete but is at least good quality.
I read over your edit and this is what I've got currently:
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->#include <string>
#include <iostream>
using namespace std;
int main()
{
string greeting1 = "Hows it going amigo la la la sup.\n"; // create a string of the text
string *myString = &greeting1; // create a pointer to the string
cout<< *myString <<endl; // output the de-referenced pointer, i.e text
int length = myString->length(); // creating integer "length" that finds the length of the pointer myString
cout<< length <<"\n" <<endl; // output the integer length
char* greeting2 = new char[length]; // create greeting2 as a char array with variable size 'length'
greeting2 = myString->c_str(); // convert myString into a c-string array-of-characters style, save as greeting2
cout<< greeting2 <<endl; // output greeting2
}<!--QuoteEnd--></div><!--QuoteEEnd-->
I'm still getting an error on "char* greeting2 = new char[length], saying:
.\5454.cpp(20) : error C2440: '=' : cannot convert from 'const char *' to 'char *'
Conversion loses qualifiers
So I don't know if it'd work and if i can do without the strcpy line.
edit: sorry, the error is with
greeting2 = myString->c_str();
not the char line.
Thanks for the links, I'll check em out tomorrow when I'm awake as well.
I read over your edit and this is what I've got currently:
I'm still getting an error on "char* greeting2 = new char[length], saying:
.\5454.cpp(20) : error C2440: '=' : cannot convert from 'const char *' to 'char *'
Conversion loses qualifiers
So I don't know if it'd work and if i can do without the strcpy line.
edit: sorry, the error is with
greeting2 = myString->c_str();
not the char line.
<!--QuoteEnd--></div><!--QuoteEEnd-->
What's happening here is that the return value of c_str() is a <!--fonto:courier--><span style="font-family:courier"><!--/fonto-->const char *<!--fontc--></span><!--/fontc-->, meaning that it's a pointer to a character that is constant. Any time you're using a pointer to a const, the compiler will prevent you from trying to set the deferenced value (since it's supposed to be a constant). In this case, c_str() returns a const char* instead of just a char* because you're not supposed to be able to edit that C string representation, though you can view it.
The thing is, here, the compiler also doesn't allow you to assign a const char* to a char *, because that would defeat the purpose of the const pointer in the first place (since it would mean you could just edit what's being pointed to via the non-const pointer). That's what the compiler means by "conversion loses qualifiers". It's perfectly ok to assign the other way around, though.
In this particular case though, there's more going wrong here.
<!--quoteo--><div class='quotetop'>QUOTE</div><div class='quotemain'><!--quotec-->char* greeting2 = new char[length];<!--QuoteEnd--></div><!--QuoteEEnd-->
This line doesn't just create an array. What you're doing here is declaring a char pointer, allocating a block of memory, and assigning the address of the first char in that block to the greeting variable.
In the next line (ignoring the const business for a moment), what happens is that calling c_str() gives you a C-style string, which is a null-terminated array of characters, which is a character pointer that points to a block of character variables. All you're actually getting is a the pointer to the start of the string, then assigning that pointer to the greeting2 pointer that you've declared. In the process, the memory you've already allocated an assigned to the greeting2 pointer is lost. This will not copy the string from the c_str() array to your array. That's the reason for the strcpy function - that's what it does.
I'll try to explain what's going on here. In C, pointers and arrays are the same thing (well, not exactly, but they are for our purposes):
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->int numbers[5];
int lastElement = numbers[4];
int firstElement = numbers[0];
int* intPointer = &numbers[0];
//so intPointer is pointing to the first element in the array
if(intPointer == numbers)
cout << "You should see this message. The numbers variable ITSELF is a pointer, pointing to a block of 5 ints, because that's all an array is - a pointer pointing to a block of values" << endl;
else
cout << "my c++ is rustier than I thought" << endl;
numbers[2] = 222;
intPointer[2] == numbers[2]; //evaluates to true also. You can use brackets to access pointers, exactly the same as arrays.
intPointer[2] == 222; //evaluates to true.
intPointer = new int[10];
//intPointer now points to a newly allocated block of 10 ints
intPointer[2] == 222;
//will almost certainly be false. intPointer is now no longer pointing to the numbers array, and is now pointing to freshly allocated memory which has not had any values assigned to it, and so will contain whatever happened to be in those memory cells at the time.
// intPointer = numbers; //this would not be a good thing to do, because the memory allocated to intPointer will become lost. instead:
delete [] intPointer; //this deallocates and releases the memory that intPointer is pointing to. The [] is because it was assigned to a block of ints instead of just one int.
intPointer = numbers;
<!--c2--></div><!--ec2-->
I said in an earlier post that you deallocate memory with "free", which shows how rusty my C++ is getting. In C++, it's "delete", not "free" (which is the old, C way of doing things and will break if combined with C++'s "new" keyword).
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->int input;
while (true)
{
cout<< "Input an integer:\n";
if (!(cin>> input))
{
cout<< "That is not a valid integer. Please try again:\n";
}
else
{
cout<< "The result is: "<< input <<endl;
break;
}
}<!--c2--></div><!--ec2-->
I think the problem is with the !(cin>> input) in the if function. It's the only way to determine that it's false, but it's not asking for extra input every time round... as it stands, it just spams "That is not a valid integer" over and over again until I forcibly quit the program.
Keeping this thread active... does anybody know what I'm doing wrong here?
<code>
I think the problem is with the !(cin>> input) in the if function. It's the only way to determine that it's false, but it's not asking for extra input every time round... as it stands, it just spams "That is not a valid integer" over and over again until I forcibly quit the program.
<!--QuoteEnd--></div><!--QuoteEEnd-->
Well, try not to use break if you can possibly avoid it (other than in switch statements) - it's not good practise because it leads to hard-to-read code.
Let me get out the big book o' C++...
...try calling cin.clear()
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->int input;
while (true)
{
cout<< "Input an integer:\n";
if (!(cin>> input))
{
cout<< "That is not a valid integer. Please try again:\n";
cin.clear();
}
else
{
cout<< "The result is: "<< input <<endl;
break;
}
}<!--c2--></div><!--ec2-->
Afaik, when an error occurs when reading to or writing from a stream, it actually sets an error state in the stream. clear() clears it, I think.
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1--> int x = 0;
do {
cout << "Enter a number (-1 = quit): ";
if(!(cin >> x)) {
cout << "Please enter numeric characters only." << endl;
cin.clear();
cin.ignore(10000,'\n');
}
else if(x != -1) {
cout << "You entered " << x << endl;
}
}
while(x != -1);
cout << "Quitting program." << endl;<!--c2--></div><!--ec2-->
The key seems to be in the cin.ignore(10000,'\n') coupled with cin.clear(). With either one missing, the same infinite-spamming error occurs. Time to look up each part and figure out how it works...
By the way, do you know any sites that offer snippets of code with an explanation of how they work? It seems like most of my problems come from either a misunderstanding [or lack of experience] of how functions and certain code works, or just not knowing required functions.
The thing is, I don't know of a good <i>C++</i> book that I'd recommend to start learning from. Lots of books (and tutorials) will teach C style C++, or C++ aimed at C programmers, and miss out important details and\or teach bad habits (I originally learned from one of those, and it ended up making things difficult).
In any case, <a href="http://www.gamedev.net" target="_blank">GameDev.net</a> has some great resources on it, mostly for developing games but also more general programming stuff - particularly on the forums.
Ah. In particular, the first three links on <a href="http://www.gamedev.net/community/forums/topic.asp?topic_id=358397" target="_blank">this</a> thread. There's tons more advice in there than I could possibly give you.