You might be looking to use strlen() instead. chFunc1 is a pointer, not an object of a class type that has a size() member function.
You might be looking to use strlen() instead. chFunc1 is a pointer, not an object of a class type that has a size() member function.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
There are two main ways to handle a string. One is to use character arrays, the other is to use the C++ string class. In C++ using the C++ string class is generally the better option, but sometimes classes/books/tutorials are old and unmodernized or just disagree and use character arrays instead.
So if you can, then I'd suggest using the C++ string class. That means using string instead of char* or char[]. The C++ string class has a function called size(), and if chFunc1 was a string then your call to size() would work.
However, if you are being taught character arrays, then I guess you should use those for now and strlen is what you need for the size. Just remember to learn C++ strings on your own later if you want to continue with C++.
can i still refer to an individual character if i use the string class?
Yes.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
ok, string class seems to help, but I have now lead myself to another problem, of which I just can't seem to figure out. I know it's a little unorthodox, but, if you don't mind, I'm going to post my entire source code here (it's not very long) to see what you guys make of it. This particular one is for a friend of mine who wants to randomly capitalize email addresses.
If you don't feel like compiling it, this is what the screen looks like...Code:#include <iostream> #include <cstdlib> #include <time.h> #include <cctype> #include <windows.h> #include <string.h> #include <fstream> #include <sstream> using namespace std; /* These constants define our upper and our lower bounds. The random numbers will always be between 1 and 12, inclusive. */ const int LOW = 1; const int HIGH = 12; string getAddy() // Get the email address from the user...pretty self-explanatory... { cout << "Enter address below: "; string addy; getline(cin,addy); cout << "\nDid you enter \"" << addy << "\"? [y|n]: "; char yn; cin >> yn; switch ( yn ) { case 'y': break; case 'n': cout << "\nPlease try again." << endl; getAddy(); default: cerr << "\nInvalid selection. Please try again." << endl; getAddy(); } return addy; } string randomize() { string addy = getAddy(); // Puts the value of getAddy into a string int len = addy.size(); // Get the length of the string string randAddy; // string usedAddies; // ifstream used_addies ("addies.txt"); // Makes sure that no two addies while (! used_addies.eof()) { // generated are the same. getline(used_addies, usedAddies); } // used_addies.close(); // stringstream str_randAddy; // for (int i=1; i <= len; i++) { if (rand() < HIGH * 0.15) { randAddy[i] = toupper(addy[i]); // Capitilize some random characters } } str_randAddy << randAddy; if (usedAddies.find(str_randAddy.str(), 0) != std::string::npos) { // If it's already been made, start over randomize(); } return randAddy; } void saveAddy() // Save the randomized addy to addies.txt ...again pretty self-explanatory... { string addy = randomize(); ofstream addies ("addies.txt", ios::app); if (addies.is_open()) { addies << addy << ", "; } /* If there was a problem opening the file, terminate the program. */ else { cerr << "Error: Could not open log file. 10 seconds 'till quit."; for (int i=10; i=0; i--) { cout << i; Sleep(1000); } abort(); } return; } int main() { getAddy(); cout << "How many addies are req'd? : "; // tells the program how many addies to generate int reqd; cin >> reqd; for (int i=0; i <= reqd; i++) { randomize(); saveAddy(); } cout << "Finished generating addies!!" << endl; system("PAUSE"); return 0; }
http://i12.tinypic.com/2vvnhvb.jpg
Last edited by jmajeremy; 04-01-2007 at 02:22 PM.
You are mixing cin >> with getline. That leads to problems because when the user types in something like the 5 to answer the How many addies are req'd question, they type 5<enter>. The <enter> leaves a newline character in the input stream, but cin >> does not read that in, it leaves it there for later. When you call getline to get the address, it looks for the next newline character and it finds the one leftover from the previous <enter>. That's why the email address is empty.
The solution is to add cin.ignore() after any call to cin >> to ensure that the newline character is ignored. You shouldn't add the ignore() after calls to getline() because unlike operator>>, getline() automatically reads and ignores the newline it finds at the end.
if i put getline(), cin.ignore(), or if i jst change it to:
, I get the same result.Code:for (int i=0; i <= 10; i++) { randomize(); saveAddy(); }
its still doing the same thing
You put cin.ignore() immediately after all calls to cin >> and it didn't change anything? Can you post your latest code with that change?
Should it be wriiten as...
?Code:cin >> var; cin.ignore(); // or cin.irgnore() >> var;
Use the former.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Here's the updated code...
...although I don't think that was the problem, because the first time I enter the addy it works, but then it tries to (unsuccessfully) do getAddy() again, even though it's written to call randomize() and then saveAddy().Code:#include <iostream> #include <cstdlib> #include <time.h> #include <cctype> #include <windows.h> #include <string.h> #include <fstream> #include <sstream> using namespace std; /* These constants define our upper and our lower bounds. The random numbers will always be between 1 and 12, inclusive. */ const int LOW = 1; const int HIGH = 12; string getAddy() // Get the email address from the user...pretty self-explanatory... { cout << "Enter address below: "; string addy; getline(cin,addy); cout << "\nDid you enter \"" << addy << "\"? [y|n]: "; char yn; cin >> yn; cin.ignore(); switch ( yn ) { case 'y': break; case 'n': cout << "\nPlease try again." << endl; getAddy(); default: cerr << "\nInvalid selection. Please try again." << endl; getAddy(); } return addy; } string randomize() { string addy = getAddy(); // Puts the value of getAddy into a string int len = addy.size(); // Get the length of the string string randAddy; // string usedAddies; // ifstream used_addies ("addies.txt"); // Makes sure that no two addies while (! used_addies.eof()) { // generated are the same. getline(used_addies, usedAddies); } // used_addies.close(); // stringstream str_randAddy; // for (int i=1; i <= len; i++) { if (rand() < HIGH * 0.15) { randAddy[i] = toupper(addy[i]); // Capitilize some random characters } } str_randAddy << randAddy; if (usedAddies.find(str_randAddy.str(), 0) != std::string::npos) { // If it's already been made, start over randomize(); } return randAddy; } void saveAddy() // Save the randomized addy to addies.txt ...again pretty self-explanatory... { string addy = randomize(); ofstream addies ("addies.txt", ios::app); if (addies.is_open()) { addies << addy << ", "; } /* If there was a problem opening the file, terminate the program. */ else { cerr << "Error: Could not open log file. 10 seconds 'till quit."; for (int i=10; i=0; i--) { cout << i; Sleep(1000); } abort(); } return; } int main() { getAddy(); cout << "How many addies are req'd? : "; // tells the program how many addies to generate int reqd; cin >> reqd; cin.ignore(); for (int i=0; i <= reqd; i++) { randomize(); saveAddy(); } cout << "Finished generating addies!!" << endl; system("PAUSE"); return 0; }
When you recur and call getAddy(), you ignore its return value. I suggest you useCode:string getAddy() // Get the email address from the user...pretty self-explanatory... { cout << "Enter address below: "; string addy; getline(cin,addy); cout << "\nDid you enter \"" << addy << "\"? [y|n]: "; char yn; cin >> yn; cin.ignore(); switch ( yn ) { case 'y': break; case 'n': cout << "\nPlease try again." << endl; getAddy(); default: cerr << "\nInvalid selection. Please try again." << endl; getAddy(); } return addy; }
in the places I have highlighted.Code:return getAddy();
First of all, you never close the file addies. If you try to open this file at a later point in the program (perhaps with this same function), it probably won't work, because it's still open. Make sure you callCode:void saveAddy() // Save the randomized addy to addies.txt ...again pretty self-explanatory... { string addy = randomize(); ofstream addies ("addies.txt", ios::app); if (addies.is_open()) { addies << addy << ", "; } /* If there was a problem opening the file, terminate the program. */ else { cerr << "Error: Could not open log file. 10 seconds 'till quit."; for (int i=10; i=0; i--) { cout << i; Sleep(1000); } abort(); } return; }
if it was opened successfully.Code:addies.close();
Secondly, the loop highlighted in red will never execute.
i=0 is always false. I'm guessing you meant i>0.Code:for (int i=10; i=0; i--) {
Thirdly, the blue-highlighted line (assuming you fix the loop) will generate output like
I suggest printing a newline after it (or to be really fancy and non-portable, '\r' ). (Also a newline or at least a space after the preceding cerr message.)Code:10987654321
Fourth, that return statement is optional.
At the end of that while loop, used_addies will contain the last line in the file. I think you probably want an array or all of the lines in the file appended to each other, unless you only want to consider the last addie.Code:string randAddy; // string usedAddies; // ifstream used_addies ("addies.txt"); // Makes sure that no two addies while (! used_addies.eof()) { // generated are the same. getline(used_addies, usedAddies); } // used_addies.close(); // stringstream str_randAddy; //
I think you're accessing beyond the end of the array there.Code:stringstream str_randAddy; // for (int i=1; i <= len; i++) { if (rand() < HIGH * 0.15) { randAddy[i] = toupper(addy[i]); // Capitilize some random characters } }
dwk
Seek and ye shall find. quaere et invenies.
"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell
Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net
My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, nort, etc.
ok, here's the updated code...
looking a bit better; it does getAddy(), then it asks me how many addies I require, but then it just does getAddy() over and over!Code:#include <iostream> #include <cstdlib> #include <time.h> #include <cctype> #include <windows.h> #include <string.h> #include <fstream> #include <sstream> using namespace std; /* These constants define our upper and our lower bounds. The random numbers will always be between 1 and 6, inclusive. */ const int LOW = 1; const int HIGH = 12; string getAddy() // Get the email address from the user...pretty self-explanatory... { cout << "Enter address below: "; string addy; getline(cin,addy); cout << "\nDid you enter \"" << addy << "\"? [y|n]: "; char yn; cin >> yn; cin.ignore(); switch ( yn ) { case 'y': break; case 'n': cout << "\nPlease try again." << endl; return getAddy(); default: cerr << "\nInvalid selection. Please try again." << endl; return getAddy(); } return addy; } string randomize() { string addy = getAddy(); // Puts the value of getAddy into a string int len = addy.size(); // Get the length of the string string randAddy; // string usedAddies; // ifstream used_addies ("addies.txt"); // Makes sure that no two addies while (! used_addies.eof()) { // generated are the same. getline(used_addies, usedAddies); } // used_addies.close(); // stringstream str_randAddy; // for (int i=1; i < len; i++) { if (rand() < HIGH * 0.15) { randAddy[i] = toupper(addy[i]); // Capitilize some random characters } } str_randAddy << randAddy; if (usedAddies.find(str_randAddy.str(), 0) != std::string::npos) { // If it's already been made, start over randomize(); } return randAddy; } void saveAddy() // Save the randomized addy to addies.txt ...again pretty self-explanatory... { string addy = randomize(); ofstream addies ("addies.txt", ios::app); if (addies.is_open()) { addies << addy << ", "; addies.close(); } /* If there was a problem opening the file, terminate the program. */ else { cerr << "Error: Could not open log file. 10 seconds 'till quit."; for (int i=10; i>0; i--) { cout << i << "...\n"; Sleep(1000); } abort(); } return; } int main() { getAddy(); cout << "How many addies are req'd? : "; // tells the program how many addies to generate int reqd; cin >> reqd; cin.ignore(); for (int i=0; i <= reqd; i++) { randomize(); saveAddy(); } cout << "Finished generating addies!!" << endl; system("PAUSE"); return 0; }
Just something I noticed . . .
If the user does not enter 'y' or 'n' when prompted, shouldn't they enter that again rather than start from the beginning and enter the address? BTW, that doesn't really need to be a recursive function; a loop would work as well.Code:string getAddy() // Get the email address from the user...pretty self-explanatory... { cout << "Enter address below: "; string addy; getline(cin,addy); cout << "\nDid you enter \"" << addy << "\"? [y|n]: "; char yn; cin >> yn; cin.ignore(); switch ( yn ) { case 'y': break; case 'n': cout << "\nPlease try again." << endl; return getAddy(); default: cerr << "\nInvalid selection. Please try again." << endl; return getAddy(); } return addy; }
Nor does randomize() . . . you like recursive functions, don't you? Ever programmed in LISP?
If the user enters 1, two addresses will be generated . . . perhaps you want <, not <=.Code:cout << "How many addies are req'd? : "; // tells the program how many addies to generate int reqd; cin >> reqd; cin.ignore(); for (int i=0; i <= reqd; i++) { randomize(); saveAddy(); }
dwk
Seek and ye shall find. quaere et invenies.
"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell
Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net
My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, nort, etc.