David W 131 Practically a Posting Shark

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) ...

David W 131 Practically a Posting Shark

Check here ...

http://www.4shared.com/folder/xPqGQHPl/class_String.html

Also see 2 demos there ...

David W 131 Practically a Posting Shark

It seeems you don't have C++ string
Try using the class String I linked to, on your other post.

David W 131 Practically a Posting Shark

Try this class String

http://www.4shared.com/folder/xPqGQHPl/class_String.html

and the test file there

David W 131 Practically a Posting Shark

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?

David W 131 Practically a Posting Shark

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 << …
David W 131 Practically a Posting Shark

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() );
}
David W 131 Practically a Posting Shark

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.)

David W 131 Practically a Posting Shark

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 …
David W 131 Practically a Posting Shark

There are numerous problems with your code.

  1. Do not use conio.h if you want portable code.
  2. Avoid the dangerous use of gets ... use fgets instead.
  3. ...
    ...

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 …
David W 131 Practically a Posting Shark

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 …
David W 131 Practically a Posting Shark

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;
}
David W 131 Practically a Posting Shark

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;
}
David W 131 Practically a Posting Shark

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 …
David W 131 Practically a Posting Shark

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).

David W 131 Practically a Posting Shark

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.)

David W 131 Practically a Posting Shark

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.) …
David W 131 Practically a Posting Shark

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 ...

David W 131 Practically a Posting Shark

Would you like to show us the program you have ...

David W 131 Practically a Posting Shark

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 ... " );
}
David W 131 Practically a Posting Shark

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()
         << ", …
David W 131 Practically a Posting Shark

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
David W 131 Practically a Posting Shark

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;
}
David W 131 Practically a Posting Shark

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;
}
David W 131 Practically a Posting Shark

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.

David W 131 Practically a Posting Shark

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

        // …
David W 131 Practically a Posting Shark
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 << …
Ezekiel_1 commented: The words I meant are the strings that will be entered by the user +0
David W 131 Practically a Posting Shark

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() );
}
David W 131 Practically a Posting Shark

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 ...
David W 131 Practically a Posting Shark

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
David W 131 Practically a Posting Shark

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( …
David W 131 Practically a Posting Shark

// 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;
}
David W 131 Practically a Posting Shark

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

David W 131 Practically a Posting Shark

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 …
David W 131 Practically a Posting Shark

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 …
David W 131 Practically a Posting Shark

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    : …
David W 131 Practically a Posting Shark

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.)

David W 131 Practically a Posting Shark

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++ ... :)

David W 131 Practically a Posting Shark

Oops ... forgot to have ...

#include <cctype> // re. tolower, toupper

So please add to code above.

David W 131 Practically a Posting Shark

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 …

David W 131 Practically a Posting Shark

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++

David W 131 Practically a Posting Shark

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 = &num;
    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 );
}
David W 131 Practically a Posting Shark

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
??

David W 131 Practically a Posting Shark

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 ;
}
David W 131 Practically a Posting Shark

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 …
David W 131 Practically a Posting Shark

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 …

David W 131 Practically a Posting Shark

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 …
David W 131 Practically a Posting Shark

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

David W 131 Practically a Posting Shark

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";
        }
    }
}
David W 131 Practically a Posting Shark

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()

jandanielsaclolo commented: Thanks! +0