Can you show us what code you have tried?
Start with a working C++ shell ... and add from there, in steps.
Show us where you are having trouble(s) ...
Can you show us what code you have tried?
Start with a working C++ shell ... and add from there, in steps.
Show us where you are having trouble(s) ...
It seeems you don't have C++ string
Try using the class String I linked to, on your other post.
Try this class String
http://www.4shared.com/folder/xPqGQHPl/class_String.html
and the test file there
Well ... that was insightful :)
Maybe ... you could switch to the C forum ... and do the code all in C?
But first? Do you have C++ strings ? Or do you need a C++ class String to use?
A working code 'shell' is just a starting sequence of code that compiles and gives the exact expected output for all accepted input ...
You are still coding in C ...
What does 'not functioning' mean?
Does your code compile?
Does your code give any output?
If so, what part(s) of output are problematic?
I thought you wanted to code in C++
Below is a working C++ 'shell' that takes (only valid) C++ string input ... and gives some (the here expected output) to prove that it is really working.
Below is only just a 'first step' ...
// stringsCppTest2.cpp // // 2014-02-26 //
// http://developers-heaven.net/forum/index.php/topic,46.0.html
#include <iostream>
#include <string>
#include <cctype> // re. isdigit
using namespace std;
// valid if not empty and only contains digits 0..9 ...
bool isValidInt( const string& n )
{
size_t len = n.size();
if( !len ) return false;
for( size_t i = 0; i < len; ++i )
if( !isdigit( n[i] ) ) return false;
// else ...
return true;
}
int main()
{
string test;
do
{
cout << "Enter 'test' string (empty string to exit) : " << flush;
getline( cin, test );
if( !isValidInt( test ) )
{
cout << "\nNot a valid integer! Try again ... \n";
continue; // jump to while test at end of loop right now ...
}
size_t len = test.size();
for( size_t i = 0; i < len; ++i )
{
cout << "char at index [" << i << …
Please show your working C++ code shell ... that takes in a valid C++ string and ...
Below is some working C++ demo code that inputs a C++ string and outouts each char ... this is just to demo a 'working shell' ... to get you started coding with C++ string.
// stringsCppTest2.cpp //
// http://developers-heaven.net/forum/index.php/topic,46.0.html
#include <iostream>
#include <string>
using namespace std;
int main()
{
string test;
do
{
cout << "Enter 'test' string (empty string to exit) : " << flush;
getline( cin, test );
size_t len = test.size();
for( size_t i = 0; i < len; ++i )
{
cout << "char at index [" << i << "] was " << test[i] << endl;
}
}
while( test.size() );
}
Conversion from any base to base 10
Is that what your example tries to do?
No!
You may glean some ideas there ... though?
If you are to code it in C++ ...
best to start to do that.
Get a working shell that takes (some) input and gives the expected output.
Then work in steps from there.
Perhaps ... code a decimal to binary conversion first
using C++ string for input of the decimal and output of the correctly matching binary formatted the way you like.
Good to firstly validate that the input string contains only digits 0..9 (and not an empty string, either.)
Here is a demo of sorting an array of struct (the array holds a 'Contact list'.)
typedef struct Contacts
{
char name[16];
int area;
int phone;
} Contacts;
Here is the program:
/*
C qsort examples ...
NOTE: needs a C compiler with qsort and const var's
demos ... qsort ...
sorting an array of struct on various fields ... and combined fields
sorting an array of C strings with (and without) ignoring case
sorting an array of int's
*/
/* this version 2010-05-16 */
/* http://developers-heaven.net/forum/index.php/topic,46.0.html */
#include <stdio.h>
#include <stdlib.h> /* qsort */
#include <string.h>
#include <ctype.h> /* tolower */
typedef struct Contacts
{
char name[16]; /* max length of name is 15 char's ... */
int area;
int phone;
} Contacts;
/* will only handle ints where difference is a valid int ... */
int compareInt( const void* x, const void* y )
{
return( *(const int*)x - *(const int*)y );
}
int compareStr( const void* x, const void* y )
{
return strcmp( *(const char**)x, *(const char**)y );
}
int compareStrIgnoreCase( const void* x, const void* y )
{
const char* s1 = *(const char**)x;
const char* s2 = *(const char**)y;
while( *s1 != 0 && *s2 != 0 )
{
if( tolower(*s1) != tolower(*s2) )
break;
++s1; ++s2;
}
/* now test end conditions .... */
return tolower(*s1) - tolower(*s2);
}
int compareContactsNameIgnoreCase( const void* x, const void* y )
{
const Contacts* c1 = (const Contacts*)x;
const Contacts* c2 …
There are numerous problems with your code.
This sample code below may help you get started ...
It is good to develope in steps, making sure that at each step your code compiles and runs with the expected output.
Always keep a copy of your last working 'step' ... so that you can go back to that (working) stage of developement and start again ... (if you can not find the 'bug').
include <stdio.h>
/* #include <conio.h> */
#include <string.h>
#include <ctype.h>
int is_alpha( char ch ) /* but why not use C provided isalpha ? */
{
return ( ch >= 'A' && ch <= 'Z' ) || ( ch >= 'a' && ch <= 'z' );
}
int main()
{
int i, str_len;
char str[ 1024 ], *p;
/* clrscr(); */
printf( "Enter a line of C code to check if valid: " );
fgets( str, sizeof(str), stdin );
p = strchr( str, '\n' );
if( p ) *p = 0; /* 0 terminate to rid '\n' char at end ... */
else
{
fputs( "The buffer size was too small ... enlarge and recompile.\n ", stderr );
getchar();
return 1;
}
str_len = strlen( str );
printf( "You entered: %s\n", str );
printf( "With length %d characters.", str_len );
for( i = 0; i < str_len; ++i )
{
/* your code here …
A first step to coding a solution to any problem is a clear understanding (and statement) of the problem.
What is the expected input (validate input to make sure ok.)
What is the desired output (is the program to loop for more input, if invalid ... or to loop again.)
A common problem, for new coders, is to handle invalid input and ... the '\n' char ... or other characters left behind in an input stream.
Once you see how to handle this ... your coding will become much more fun!
You may like to see the example below ...
/* getValidInt.c */ /* 2012-08-11 */
/* this demo takes in valid int's and sums them ... */
/* http://developers-heaven.net/forum/index.php/topic,46.0.html */
#include <stdio.h>
int getValidInt( const char prompt[] )
{
for( ; ; ) /* an example of a C/C++ forever loop ... until 'return' */
{
int numGood, testInt;
fputs( prompt, stdout );
fflush( stdout );
numGood = fscanf( stdin, "%d", &testInt );
while( getchar() != '\n' ); /* 'flush' stdin ... as we go ... */
if( numGood == 1 ) return testInt;
/*else ...*/
puts( "Invalid input! Integers only please ..." );
}
}
int more() /* defaults to 'true'/'yes'/'1' ... unless 'n' or 'N' entered */
{
int reply;
fputs( "More (y/n) ? ", stdout );
fflush( stdout );
reply = getchar();
if( reply != '\n' ) while( getchar() != '\n' ); /* 'flush' stdin buffer */
if( reply == 'n' || reply …
Where is your 'int main()' function ?
Every C or C++ program needs one.
#include <iostream> // use < > brackets
using namespace std;
int main()
{
// your code goes here ...
double monthly_sales, commission;
bool more = true;
do // main loop where you input & output ...
{
cout << "Enter monthly sales: " << flush;
cin >> monthly_sales;
while( cin.get() != '\n' ); // eat '\n' etc.
// your code goes here to calculate and
// output results ...
cout << "More (y/n) ? " << flush;
int reply = cin.get();
if( reply != '\n' ) while( cin.get() != '\n' ) ; // flush cin stream ...
more = (reply != 'n' && reply != 'N' ); // defaults to yes (more) ...
}
while( more );
return 0;
}
You could use the above example (copied now here below):
char takeInChar( const string& msg )
{
cout << msg << flush;
string reply;
getline( cin, reply );
if( reply.size() )
return reply[0];
// else ...
return 0;
}
bool more() // defaults to yes (more) ...
{
if( tolower( takeInChar( "\nMore (y/n) ? " )) == 'n' )
return false;
// else ...
return true;
}
Your coding work can be made SO MUCH easier ... if you JUST use a vector to hold the cites ... in the main program.
(Then you can use the STL supplied vector iterators, etc..)
See this running start:
(Note all the code (sections) that has (have) /* not used here */ around it, as that code (section) is not needed to do the jobs requested.
// distanceTwoCities.cpp //
#include <iostream>
//#include <fstream>
#include <string>
#include <vector>
#include <cmath>
//#include <cctype>
using namespace std;
const string MENU = "Please choose from the following options below: \n"
"1. Add a city \n"
"2. Calculate distance between cities \n"
"3. Print all cities \n"
"4. Delete a city \n"
"5. Quit \n";
class Point
{
public:
Point(void);
/*
Point(double new_x, double new_y);
Point(const Point & p);
void set_x(double new_x) { x = new_x; }
void set_y(double new_y) { y = new_y; }
double get_x(void) const { return x; }
double get_y(void) const { return y; }
*/
void takeIn(void);
double distance (const Point & other) const;
private:
double x, y;
friend ostream& operator << ( ostream& os, const Point& p )
{
return os << p.x << ", " << p.y;
}
} ;
Point::Point(void)
{
x = y = 0.0;
}
/*
Point::Point(double new_x, double new_y)
{
x = new_x;
y = new_y;
}
Point::Point(const Point & p)
{
x = p.x;
y = p.y;
}
*/
void Point::takeIn(void)
{
char comma;
for( ; ; )
{
cout << "Enter …
Yes ... but here, you seem to NOT want (or need) any code to handle file input ...
since you are getting input from the keyboard to fill up a test vector of strings to sort, etc.
So ... just use code that does that job ... input test strings into an (initially empty) vector of strings, from the keyboard ... as per user input function example(s).
You seem to be coding in C here in the C++ coding forum.
This may be better handled in the C coding area?
Not good to use conio.h stuff
Shun the dangerous use of gets in C
(I use my own readLine to handle the dynamic allocation of C strings that are to be input from a user or file.)
Also ... it would be best to accept ONLY valid input from the user ... (if you are NOT using input from a valid data file) ...
You could do that, coding for your user input function, something like below:
bool isAllDigit( const string& s )
{
for( int i = s.size()-1; i >= 0; -- i )
{
if( !isdigit(s[i]) ) return false;
}
return true;
}
bool isAllAlpha( const string& s )
{
for( int i = s.size()-1; i >= 0; -- i )
{
if( !isalpha(s[i]) ) return false;
}
return true;
}
bool isValid( const string& s )
{
if( isAllDigit(s) ) return true;
if( isAllAlpha(s) ) return true;
size_t pos = s.find_first_of( "0123456789" );
bool valid = true;
if( pos == string::npos ) valid = false; // not likely ... just in case
else if( isAllAlpha( s.substr( 0, pos )) && isAllDigit( s.substr( pos )) )
return true;
else valid = false;
cout << "\nInvalid input ... please try again ...\n";
return valid;
}
// valid line entry only ...
// 1. a valid int (only one valid int on line)
// 2. a string (no embedded digits 0..9)
// 3. a string (as in 2.) immediately followed by one valid int
void loadFromUser( VecStr& vs )
{
cout << "Valid input here is:\n"
<< "1. a valid integer (only one valid int on line ... or\n"
<< "2. a string (no embedded digits 0..9) ... or\n"
<< "3. a string (as in 2.) …
Since you are using C++ ...
Why not just easily USE C++ string ...
Then ...
your program to input strings into a vector of strings ...
and to sort them, as you wish ...
(code and use your own compare function for the sort
... see or use the example compare function used above)
can easily all be done in just ONE short file.
Using the C++ STL ... for vector and sort, etc...
IS THE WAY to go !
Please review the examples and functions provided above.
You really do have all that you need there, using C++ string and the C++ STL ...
Would you like to show us the program you have ...
What do you want to have in your main function ...
Maybe ... something like this:
int main()
{
VecStr vs; // construct empty vector ...
loadFromUser( vs );
cout << "Before sorting ... \n";
print( vs );
sort( vs.begin(), vs.end(), myCmp );
cout << "After sorting ... \n";
print( vs );
pause( "Press 'Enter' to continue/exit ... " );
}
Since your are using C++, why not rather use C++ strings?
// structStudent.cpp // // 2014-02-25 //
#include <iostream>
#include <string>
using namespace std;
struct Student
{
private:
string firstName;
string lastName;
string telephone;
public:
void set_firstName( const string& fn ) { firstName = fn; }
void set_lastName( const string& ln ) { lastName = ln; }
void set_telephone( const string& ph ) { telephone = ph; }
string get_firstName() const { return firstName; }
string get_lastName() const { return lastName; }
string get_telephone() const { return telephone; }
void takeIn()
{
cout << "Enter first name : " << flush;
getline( cin, firstName );
cout << "Enter last name : " << flush;
getline( cin, lastName );
cout << "Enter telephone : " << flush;
getline( cin, telephone );
}
void print() const
{
cout << "Student info: " << endl;
cout << "Name: " << firstName << " " << lastName
<< ", Telephone: " << telephone << endl;
}
} ;
// vs ...
void takeIn( Student& s )
{
string tmp;
cout << "Enter first name : " << flush;
getline( cin, tmp );
s.set_firstName( tmp );
cout << "Enter last name : " << flush;
getline( cin, tmp );
s.set_lastName( tmp );
cout << "Enter telephone : " << flush;
getline( cin, tmp );
s.set_telephone( tmp );
}
void print( const Student& s)
{
cout << "Student info: " << endl;
cout << "Name: " << s.get_firstName() << " " << s.get_lastName()
<< ", …
If you remember that pointer variables hold addresses, you will be well on your way.
Just remember to 'dereference' that pointer, when you wish access the value at 'that address' !!!
Pointers are an example of the use of indirect addressing.
int x = 10;
int* p_x = &x; // p_x now holds the address of an 'int' variable, the int variable x
printf( "%d\n", x ); // direct addressing
printf( "%d\n", *p_x ); // indirect addressing
To get you started ...
pseudocode/comments could look something like the following ...
#include <stdio.h>
int main()
{
// declare variables
// input with prompt to user, the lower starting value
// input ... , the upper ending value
// input ... , the 'step' value
// using a for loop ... from startVal to endVal
// calculate and output a table of corresponding values
return 0;
}
This modified code example may help you to see what is being done as the program executes ...
/* permutationsOfString.c */ /* 2014-02-25 */
/*
I have an example, coded in C, for printing all permutation of string.
I have a problem in understanding,
how recursion works in a for loop
and how backtracking is used in this code.
Another question is that how stack work in recursion under for loop.
code-->
*/
# include <stdio.h>
#define show 1
void swap( char* x, char* y )
{
char tmp = *x;
*x = *y;
*y = tmp;
}
void permute( char* a, int i, int n )
{
int j;
static int count = 0;
if( i == n )
{
printf( "%s, i=%d, count=%d\n", a, i, ++count );
#if show
putchar( '\n' );
#endif
}
else
{
for( j = i; j <= n; ++j )
{
#if show
printf( "%s, i=%d, j=%d\n", a, i, j );
#endif
swap( (a+i), (a+j) );
permute( a, i+1, n );
swap( (a+i), (a+j) ); /* backtrack */
}
}
}
int main()
{
char a[] = "ABCD";
permute( a, 0, 3 );
printf( "Press 'Enter' to continue/exit ... " );
getchar();
return 0;
}
give me coding for search and edit a file in c++
Can you supply an example of the types of files you wish to search ... and the types of editing that you wish to do?
Also, please show the code that you have coded so far, to do the desired job.
You may like to see this example ... that uses 'real words' found in some dictionary
// twoWords_dictionaryLookUp.cpp // // 2014-02-25 //
// program to be able to take in two words and
// compare them ... outputing the words from word1 which
// are also in word2 and ... vice-versa.
// note: some debugging print-out info left-in ... in this version //
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <set> // to hold dictionaries (of words)
#include <algorithm> // re. find
#include <cctype> // re. tolower
using namespace std;
#define DICT_FNAME "myDictionary.txt" //"infl.txt"
typedef set < string > Dict;
// parses out only words (from word) that are 2 letters or more ...
// that are IN the (big) Dict of words loaded in from file DICT_FNAME
void parseOutWords( const string& word, Dict& td, const Dict& d );
bool loadDictionaryFromFile( Dict& d );
void showDictionary( const Dict& d );
// utilities used here ...
void toAllLower( string& val )
{
size_t len = val.size();
while( len )
{
--len;
val[len] = tolower( val[len] );
}
}
char takeInChar( const string& msg )
{
cout << msg << flush;
string reply;
getline( cin, reply );
if( reply.size() )
return reply[0];
// else ...
return 0;
}
bool more()
{
if( tolower( takeInChar( "More (y/n) ? " )) == 'n' )
return false;
// else ...
return true;
}
int main()
{
Dict d;
if( loadDictionaryFromFile( d ) )
{
string word1, word2; //construct two empty words
// …
string spc( 3, ' ' );
cout << '*' << spc << '*';
Is short code ...
But ... what is a 'word' ? Does it need to be a real word that is in the English dictionary? If so ... that is NOT what you are doing.
See this for starters on a dictionary lookup for your words ...
// twoWords.cpp // // 2014-02-24 //
// program to be able to take in two words and
// compare them ... outputing the words from word1 which
// are also in word2 and ... vice-versa.
#include <iostream> // for cin, cout
#include <vector>
#include <string>
#include <iomanip>
#include <algorithm> // re. find
using namespace std;
typedef vector< string > VecStr;
char takeInChar( const string& msg )
{
cout << msg << flush;
string reply;
getline( cin, reply );
if( reply.size() )
return reply[0];
// else ...
return 0;
}
bool more()
{
if( tolower( takeInChar( "More (y/n) ? " )) == 'n' )
return false;
// else ...
return true;
}
int main()
{
string word1, word2; //declaration of words
// Welcome message
cout << "------------------------------------------------\n"
<< " Topiloe's Text Analyzer - Release 1.0 \n"
<< "------------------------------------------------\n\n";
cout << "Enter two words on one line (separated by a space): ";
cin >> word1 >> word2;
string dummy;
getline( cin, dummy ); // eat '\n', etc... that's still at end of cin stream
cout << "The words entered were: " << word1 << ", " << word2 << …
These may help ... (edit out the file stuff, also, of course.)
typedef vector< string > VecStr;
char takeInChar( const string& msg )
{
cout << msg << flush;
string reply;
getline( cin, reply );
if( reply.size() )
return reply[0];
// else ...
return 0;
}
bool more()
{
if( tolower( takeInChar( "\nMore (y/n) ? " )) == 'n' )
return false;
// else ...
return true;
}
void loadFromUser( VecStr& vs )
{
do
{
string line;
cout << "Enter next line: " << flush;
getline( cin, line );
vs.push_back( line );
}
while( more() );
}
My output, for the test file above, as input, was:
(matches your request ...yes?)
Before sorting ...
1
10
2
9
a1
b10
a10
a2
a9
b1
b2
After sorting ...
1
2
9
10
a1
a2
a9
a10
b1
b2
b10
Press 'Enter' to continue/exit ...
Try it with this small test 'text file', and name the file to match the file name used in the program ...
"alphaNum.txt"
It is easy (easier sometimes) to test out a program using file data ... that is 'known to be valid data'
1
10
2
9
a1
b10
a10
a2
a9
b1
b2
If your input data is close to what you show above ...
something like the following could do ...
/* sortAlphaNum.cpp */ /* 2020-02-24 */
/*
Here is what I have to do:
To have numbers sorted properly even when they aren't justified with leading 0's:
1
2
...
9
10
Instead of:
1
10
2
...
9
Also to have numbers sorted properly even if they aren't in the lead of the string:
a1
a2
...
a9
a10
b1
b2
...
Instead of:
a1
a10
a2
...
a9
b1
b10
b2
...
*/
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm> // sort
#include <cctype> // re. isdigit
using namespace std;
#define FNAME "alphaNum.txt"
typedef vector< string > VecStr;
bool loadFromFile( VecStr& vs )
{
ifstream fin( FNAME );
if( fin )
{
string line;
while( getline(fin, line) )
vs.push_back( line );
fin.close();
return true;
}
return false;
}
void print( const VecStr& vs )
{
for( size_t i = 0; i < vs.size(); ++i ) cout << vs[i] << endl;
}
void pause( const char* msg )
{
cout << msg << flush;
while( cin.get() != '\n' ) ;
}
int toInt( const string& s )
{
istringstream iss(s);
int tmp;
iss >> tmp;
return tmp;
}
struct Item
{
string s;
int val;
} ;
bool myCmp( const string& a, const string& b )
{
Item a_itm, b_itm;
istringstream iss_a(a), iss_b(b);
char c;
string tmp;
while( iss_a >> c )
{
if( …
// an example of processing the above example data ...
/* binaryOpsFromFile.c */ /* 2013-08-19 */
#include <stdio.h>
/* example file */
#define FNAME "numDat.txt"
/*
23.2 + -11.7
-11 * -77.9
128.99 / -11
23.91 - 123.99
55.5 / 0
.33 / 100
*/
void showAopB( double a, char op, double b )
{
double result = 0.0;
switch( op )
{
case '+' : result = a + b; break;
case '-' : result = a - b; break;
case '*' : result = a * b; break;
case '/' : if( b == 0.0 )
printf( "Invalid ==> " );
result = ( b == 0 ? 0 : a/b );
break;
default : printf( "%f %c %f NOT defined ... \n", a, op, b );
}
printf( "%fa %c %f = %f\n", a, op, b, result );
}
int main()
{
FILE* fin = fopen( FNAME, "r" );
if( fin )
{
double a, b;
char op;
while
(
fscanf( fin, "%lf", &a ) == 1 &&
fscanf( fin, " %c", &op ) == 1 && /* skip any leading ws */
fscanf( fin, "%lf", &b ) == 1
)
showAopB( a, op, b );
fclose( fin );
}
else printf( "\nThere was a problem opening file %s", FNAME );
printf( "\nPress 'Enter' to continue/exit ... " );
fflush( stdout ) ;
getchar();
return 0;
}
if each line in the file is exactly
numberA someBinaryOp number B
then the problem is a breeze
//example file:
23.2 + -11.7
-11 * -77.9
128.99 / -11
23.91 - 123.99
If you were to use stringstream objects, your file conversion from ..
7 regular data 'words' on each line ...
to ...
all 7 sequential words on their own sequential line,
(with the exception that the 2nd and 3rd words are both on the 2nd line, separated by one space) ...
If you were to use stringstream objects, your file conversion from ..
7 regular data 'words' on each line ...
to ...
all 7 sequential words on their own sequential line,
(with the exception that the 2nd and 3rd words are both on the 2nd line, separated by one space) ...
This becomes really easy, (once you see the facility of using stringstream to parse a line) ...
This becomes really easy, (once you see the facility of using stringstream to parse a line) ...
// fileLineToSequenceData.cpp // // 0213-08-19 //
#include <iostream>
#include <fstream>
#include <sstream> // re. stringstream obj's ...
#include <string>
using namespace std;
const char* FNAME_IN = "inDat.txt";
const char* FNAME_OUT = "outDat.txt";
/*
10BCE0014 Manohar Khanna 4 CSE613 CSE501 CSE613
10BCE0023 Vijay Ahari 4 ENG401 CSE503 CSE401
10BCE0147 Prakhar Dixit 4 CSE503 CSE623 CSE501
11BCE0258 Abdul Kadir 3 ENG301 CSE502 CSE613
11BCE0321 Rahul Garg 3 ENG301 CSE503 CSE501
11BCE0326 Bhavya Jain 3 CSE301 CSE421 CSE512
12BCE0026 Rakesh Kapoor 2 ENG201 CSE302 CSE303
12BCE0265 Sonam Krishna 2 ENG401 CSE512 CSE413
12BCE0413 Vinay Khatri 2 ENG201 CSE301 CSE203
13BCE0002 Karan Lodha 1 ENG102 CSE102 CSE301
13BCE0041 Shyam Gupta 1 ENG101 CSE101 CSE102 …
And here is a version, using Mike's ideas ... but adapting the code to do all the particular condition testing that I choose (for this example) ...
This code needs a C++11 compiler.
It uses lambda functions, etc... (instead of functors as used above) ...
(Just all in one file here ...to ease your testing.)
// takeInStuff_C++11.cpp //
// uses C++11 lambda functions like: []( int i ) { return i > 0; }
// uses C++11 (for each) function like: for( char& c : inResultCstr )
#include <iostream>
#include <cctype>
namespace TakeIns
{
template < typename T >
bool get_from_cin( T& val )
{
std::cin >> val;
return std::cin && std::cin.get() == '\n';
}
inline
bool get_from_cin( std::string& s )
{
getline( std::cin, s );
return std::cin;
}
inline
bool get_from_cin( char& c )
{
std::string s;
getline( std::cin, s );
if( s.size() )
c = s[0];
else c = 0;
return std::cin && s.size() <= 1;
}
// takeIn (in a loop) until valid ...
// with a condition to meet before accepting ... //
template < typename T, typename Predicate >
T takeIn( const std::string& msg, const Predicate& pred,
const std::string& errMsg = "\nInvalid input!\n" )
{
T result = T();
while( true )
{
std::cout << msg;
if( get_from_cin(result) && pred(result) )
{
std::cin.sync();
break;
}
else
{
std::cout << errMsg;
std::cin.clear();
std::cin.sync();
}
}
return result;
}
// takeIn (in a loop) until valid type before accepting ... //
// this is needed by …
Here is a version that doesn't need a C++11 compiler to compile ... but uses functors ... so that the programmer can pass in a 'functor' ... a 'function' that here, is used, to help validate the desired input.
A little test program will be followed by a file holding the input 'helper' routines ... in their own namespace.
// test_takeInStuff.h.cpp //
#include "takeIns.h"
// functor def'n needed by following 'takeInString'
struct NoBlankLine
{
// ctor...
NoBlankLine( bool noEmpty ) : yes( noEmpty ) {}
// def'n of overloaded operator () for NoBlankLine
bool operator() ( const std::string& s ) const
{ return yes ? s.size() : true; }
private:
bool yes;
} ;
// will not accept an empty string if noEmpty has default value of true
std::string takeInString( const std::string& msg, bool noEmpty = true )
{
// firstly, input string using TakeIns::takeIn (with condition):
std::string result = TakeIns::takeIn < std::string, NoBlankLine >
(
msg,
NoBlankLine( noEmpty ),
"\nBlank line not valid here!\n"
);
return result;
}
// 3 more functor def'ns needed in main ...
struct GreaterThanIntZero
{
bool operator() ( int i ) const { return i > 0; }
} ;
struct NoNegs
{
bool operator() ( double i ) const { return i >= 0.0; }
} ;
struct MaleFemale
{
bool operator() ( char i ) const { return i == 'm' || i == 'f'; }
} ;
int main()
{
do
{
std::string name = takeInString( "Enter your name : …
Hey Mike ... that sure was one super post :)
But I can't help smile a bit more ...
I'm not sure this is really what you should expect a beginner to produce... seems a bit too advanced. Anyways, here are ...
It seems to me ...that a big part of the frustration with some (many?) C/C++ beginners is getting past the 'tricks' of getting valid (especially numeric) input (from a user entering numbers at a keyboard) ?
Thus, I really do appreciate all the code you demo'd.
However, as you noted, things may (quickly) get 'too advanced' for a beginner :)
The goal of designing ...
're-usable generaic code'
vs
'keep it simple' to handle (mainly) 'the job at hand'
...
well ... we can see that ...
it is easy to get carried away :)
So, using the great stuff from your post, here is a suggested first (big) step towards input validation, directed especially at beginners getting (individual data record fields of) meaningful numeric input, without the running program crashing on invalid entries.
Note: this '1st step' does NOT use C++11 stuff like lambda functions or even pre-C++11 functors ...
(Other more advanced suggested steps that use C++ functors may follow ... finally with a C++11 version that uses lambda functions ... etc ... just in case there may be some really keen student here who might like to see all these steps ... that Mike has been so good to have suggested.)
…Because things, these days, seem a little 'slow' around this forum, please forebare this old post, (that was recently resurrected by an inquiring mind), and humour this 'update', in good faith that this update might be appreciated by some beginning students of C++ ... :)
Oops ... forgot to have ...
#include <cctype> // re. tolower, toupper
So please add to code above.
Because things, these days, seem a little 'slow' around this forum, please forebare this old post, (that was recently resurrected by an inquiring mind), and humour this 'update', in good faith that this update might be appreciated by some beginning students of C++ ... :)
// beginnerBadCppExampleCodeBeforeFixedUp.cpp // 2013-08-14 //
// This following 'Supposed example' of good code is ...
// re-worked ...
// to demo an acceptable coding style for current C++ students ...
#include<iostream.h>
#include<conio.h>
float no,price[50],total[50],qty[50],tt;
char item[30];
void main()
{
int i,j;
clrscr();
cout<<"\n\n\t\t\tRaje's Billing Software\n\n";
cout<<"\nEnter The Number of Products you'v Purchased:";
cin>>no;
cout<<"\n\nSL No\tITEM NAME\tQUANTITY\tPRICE/ITEM\n\n";
for(i=1;i<=no;i++)
{
cout<<i;
cout<<"\t";
cin>>item;
cout<<"\t";
cin>>qty[i];
cout<<"\t";
cin>>price[i];
total[i]=price[i]*qty[i];
cout<<"\n\n";
}
for(i=1;i<=no;i++)
{
tt=tt+total[i];
}
cout<<"\n\n\t\t\tTOTAL:"<<tt<<" Rupees";
cout<<"\n\n\t\t\tTHANK YOU VISIT AGAIN.....";
getch();
}
As DaniWeb Nick Evans rightly indicated (a long time ago) ...
I'm sorry to tell you, but this code is just horrible;
people should never ever use this snippet.
1. void main() does not exist in standard C++
2. neither does iostream.h or conio.h.
They are only used by Turbo C which is only used by people
from India and the Philippines for some reason.
The rest of the world uses IDE's from this millennium.
3. Global variables. Yuck.
4. No indention. Double yuck.
5. neither getch() or clrsrc() are valid C++ functions
6. No error control on input what-so-ever."
Ok ...
here is how it might be re-worked ...
to …
Great post Jason !
In C++ when you call:
fout << value << std::endl;
the C++ compiler 'knows' what type of object 'value' is and will output what '<<' is supposed to do for that C++ type of object ... (if '<<' is defined for that object)
Note: you can overload << for your newly defined objects in C++
Well ... best to avoid C code style and also avoid pointers in C++ unless REALLY needed ... (C++ has pass by reference)
//#include<stdio.h>
// #include <cstdio> // but use <iostream>
// #include<conio.h> // don't use to have portable code
// #include<iostream.h> // use as belowe ...
#include <iostream>
#include <string> // added ... //
// need this also in C++
// and ok for students simple code to place here
using namespace std;
int main()
{
int num; // all this next stuff is valid code //
int *ptr;
ptr = #
cout << ptr;
//cout << ptr++; // except this !!! //
// cout<<ptr; // ..... NO memory here KNOWN //
cout << sizeof(num);
// getch(); // don't use for portable code ... use
cout << "\nPress 'Enter' to continue/exit ... " << flush;
string dummy;
getline( cin, dummy );
}
Also ...
Good to get into habit of using initialization list ...
// rather than code ... (in constructors)
person :: person(string pname, int page)
{
name = pname ;
age = page ;
}
Use this instead ...
// code like this ...
person :: person( string pname, int page )
: name( pname ), age ( page ) {}
Note: the order of assignments must be the same as the top down order that the data members appeared in the class
Recall that in a class the data is ALL supposed to have initial values
The default for a string type is ""
But you must supply initial values for types like ...
int
float
double
??
Also, a few pretty basic coding suggestions ...
int main()
{
//cin.clear() ; // clears the buffer// <- NO ... it clears cin (error) flags that were set on some cin input //
// ...
//system("PAUSE") ; // Not portable code //
cout << "\nPress 'Enter' to continue/exit ... " << flush;
string dummy;
cin.clear(); // may need this if cin flags were set above and not yet cleared //
getline( cin, dummy );
return 0 ;
}
Or ... you may just want something very simple like this:
/* partition_C_ary_4.c */
/*
I have an array of integers. Let's assume int a[5]={1,2,1,2,2};
I want to divide this array into two arrays by extracting some
elements of array "a[5]" into some different arrays like "b[2]"
and "c[3]",such that int b[2] will contain {1,2} and int c[3]
will contain {1,2,2}. How can it be possible using C programming?
*/
#include <stdio.h>
void print( const int ary[], int size )
{
int i;
for( i = 0; i < size; ++i ) printf( "%d ", ary[i] );
}
int main()
{
int a[] = { 1, 2, 1, 1, 2 },
*b,
*c,
len_a = sizeof(a) / sizeof(a[0]),
len_b = 2,
len_c = 3;
b = a; /* start address of b */
c = a+2; /* start address of c, using pointer arithmetic */
puts( "All a ... " );
print( a, len_a );
putchar( '\n' );
puts( "All b ... " );
print( b, len_b );
putchar( '\n' );
puts( "All c ... " );
print( c, len_c );
printf( "\n\nPress 'Enter' to continue/exit ... " );
fflush( stdout );
getchar();
return 0;
}
Or ... merging this approach with the previous 'isEven' example partion above ...
that passed in the partion function using a function pointer ...
/* partition_C_ary_3.c */
#include <stdio.h>
void print( const int ary[], int size )
{
int i;
for( i = 0; i < size; ++i ) printf( "%d …
If you don't know about dynamic memory or function pointers ...
you can just do this modification of the above ...
/* partition_C_ary.c */
#include <stdio.h>
/* my partion 'truth function' used here ... */
int isEven( int a )
{
return a % 2 == 0;
}
void partition( int a[], int lena, int b[], int* lenb, int c[],
int* lenc ) /* Note all the passing of addressess */
{
int i;
*lenb = *lenc = 0;
for( i = 0; i < lena; ++i )
{
if( isEven(a[i]) ) /* if a[i] is true ... then */
b[(*lenb)++] = a[i];
else
c[(*lenc)++] = a[i];/* see above */
}
}
void print( const int ary[], int size )
{
int i;
for( i = 0; i < size; ++i ) printf( "%d ", ary[i] );
putchar( '\n' );
}
int main()
{
int a[] = { 5, 4, 3, 2, 1 },
b[ 5 ], /* get memory to hold all, just in case ... */
c[ 5 ],
lena = 5,
lenb = 0,
lenc = 0;
/* Passing in addresses of lenb, lenc ...
Note that isEven is 'already an address' */
partition( a, lena, b, &lenb, c, &lenc );
print( a, lena );
print( b, lenb );
print( c, lenc );
printf( "\nPress 'Enter' to continue/exit ... " );
fflush( stdout );
getchar();
return 0;
}
But if you would like to use (or learn about using) function pointers ... (so you can …
There were actually several problems with the code ... please see added comments, fixes and ... small test program ...
// test_DoublyLinkedList.h.cpp //
#ifndef DoublyLinkedList_H
#define DoublyLinkedList_H
#include <iostream>
#include <cassert>
//Definition of the node
template < class Type >
struct NodeType
{
Type info;
NodeType < Type >* next;
NodeType < Type >* back;
// ctor added ... //
NodeType( const Type& info = Type(0) )
: info(info), next(NULL), back(NULL) {}
} ;
template < class Type >
class DoublyLinkedList
{
public:
DoublyLinkedList();
//default constructor
//Initializes the list to an empty state.
//Postcondition: first = NULL; last = NULL; count = 0;
DoublyLinkedList( const DoublyLinkedList< Type >& otherList );
//copy constructor
~DoublyLinkedList();
//destructor
const DoublyLinkedList< Type >& operator =
( const DoublyLinkedList< Type > & );
//Overload the assignment operator.
//void initializeList(); // redundant ... same as 'clear' //
//Function to initialize the list to an empty state.
//Postcondition: first = NULL; last = NULL; count = 0;
bool empty() const;
//Function to determine whether the list is empty.
//Postcondition: Returns true if the list is empty,
// otherwise returns false.
void clear(); // more consistent with general use to name 'clear()'
//Function to delete all the nodes from the list.
//Postcondition: first = NULL; last = NULL; count = 0;
void print() const;
//Function to output the info contained in each node.
void reversePrint() const;
//Function to output the info contained in each node
//in reverse order.
int size() const;
//Function to return the number of nodes …
This method only works for counting the frequency of int's
(or objects that can be mapped uniquely onto int's)
NOTE:
Your array to hold the frequency of the occurence of some value is going to be a 1 D array!
(SINCE you are mapping the values in your matrix, of any dimension, to the index of an int array.
THUS, you map ...
lowest_value_in_matrix -> 0 INDEX
highest_val_in_matrx -> highest_val_in_matrix - lowest_value_in_matrix
for example ...
if in your multi-D matrix, the int values range from -1 to 10
you would need an array of int initialized all to zero to count possible incidences of values
mapped onto the range of indicies from ...
0..11
-1 -> 0
0 -> 1
...
10 -> 11
so ... declare
int ary[12] = {0};
then when done traversing the int matrix ... and updating the int array, for the frequency of the values in the matrix ...
the count stored at ary[11] represents the number of occurances of the value 10
...
the count stored at ary[0] represents the number of occurances of the value -1
Here is a start to some C++ revision of your code ...
#include <iostream>
// #include <conio.h> // avoid as it is not standard so code will not be portable
// take in two integers and return the sum
void takeInAandBandReturnSum( int& result )
{
bool ok = false;
while( !ok )
{
int a, b;
std::cout << "Enter Numbers a and b separated by a space : " << std::flush;
if( std::cin >> a >> b && std::cin.get() == '\n' )
{
result = a + b;
ok = true;
}
else
{
std::cin.clear(); // clear cin error flags
std::cin.sync(); // 'flush' cin stream ...
std::cout << "\nInvalid data ... try again.\n";
}
}
}
You said you were learning C++ ... but did you realize that your code was in the C style?
In C++, one can pass by reference ... and so will not have to dereference a value passed into a function using the * dereference operator (that is used with passed in pointers that one wants to dereference)
And note that main returns an int
so it is ...
int main() // not void main()