Re: Newbie needs help

From: Jon Bell (jtbellq2f_at_presby.edu)
Date: 11/18/03

  • Next message: Perry St-Germain: "C++ and persistent objects"
    Date: Tue, 18 Nov 2003 01:57:36 +0000 (UTC)
    
    

    In article <hKcub.3211$vb6.28441643@news-text.cableinet.net>,
    Rich Strang <riky_rang@hotmail.com> wrote:
    >
    >[...] Without the loop the program works fine with the
    >loop the cout doesn't seem to work,
    [snip]
    > if(cInput[0] != 'e' && cInput[1] != 'x' && cInput[2] != 'i' && cInput[3]
    >!= 't' )

    Here's your problem. You want to exit the loop when the user types
    "exit", right? That means you want to exit when

    cInput[0] == 'e' && cInput[1] == 'x' && cInput[2] == 'i' &&
    cInput[3] == 't'

    Your loop design means that you actually need the *opposite* of this
    condition, which is *not* what you wrote above, but rather

    cInput[0] != 'e' || cInput[1] != 'x' || cInput[2] != 'i' ||
    cInput[3] != 't'

    Think about it a bit, and if you don't "get" it, look up DeMorgan's Rule
    in a logic primer or a Google search.

    Now, here's a piece of general advice. You must be using an old C++
    textbook (pre-1998 or thereabouts), because standard header files don't
    have .h in them, and the standard came into existence around 1998.
    Post-1998 standard C++ has stuff in it that greatly simplifies what you're
    trying to do. Parsing text character by character just to split up
    whitespace-separated tokens is *sooo* 1990s. ;-)

    Here's my stab at what I think you're trying to accomplish, in more or
    less 21st-century C++ style:

    #include <iostream>
    #include <cctype>
    #include <vector>
    #include <string>
    #include <sstream>

    using namespace std;

    // no need for your GetLine function, standard C++ has one already
    void ParseLine (const string& cInput, vector<string>& cTokens);
    void PrintTokens (const vector<string>& cTokens);

    int main ()
    {
        // strings are like arrays of char on steroids
        string cInput;
        // vectors are like arrays on steroids
        vector<string> cTokens;
        int iExit = 0;
        while (iExit == 0)
        {
            cout << "$ ";
            getline (cin, cInput); // cInput automatically expands as needed
                                    // to accommodate the input
            ParseLine (cInput, cTokens);
            if (cTokens[0] == "exit") // can compare strings w/o any fuss
            {
                iExit = 1;
            }
            else
            {
                PrintTokens (cTokens);
            }
        }
        return 0;
    }

    void ParseLine (const string& cInput, vector<string>& cTokens)
    {
        cTokens.resize(0); // empty out the vector from the previous line
        istringstream linestream (cInput);
        string token;
        // read from an istringstream just like you read from cin;
        // this reads whitespace-separated tokens until it hits the
        // end of the stream
        while (linestream >> token)
        {
            cTokens.push_back(token); // cTokens automatically expands
                                       // as needed
        }
    }

    void PrintTokens (const vector<string>& cTokens)
    {
    // note vectors and strings can tell you how big they are, so you
    // don't have to keep track of it yourself
        for (int iIndex1 = 0; iIndex1 < cTokens.size(); iIndex1++)
        {
            for (int iIndex2 = 0; iIndex2 < cTokens[iIndex1].length();
              iIndex2++)
            {
                // isalnum means "isalpha || isdigit"
                if (isalnum (cTokens[iIndex1][iIndex2]))
                {
                    cout << cTokens[iIndex1][iIndex2];
                }
            }
            cout << '\n';
        }
    }

    Personally, I'd write a separate function to strip the non-alphanumeric
    stuff out of a token:

    string StripNonAlnum (const string& token)
    {
        string newToken;
        for (int k = 0; k < token.size(); ++k)
        {
            if (isalnum(token[k]))
            {
                newToken += token[k];
            }
        }
        return newToken;
    }

    void PrintTokens (const vector<string>& cTokens)
    {
        for (int iIndex1 = 0; iIndex1 < cTokens.size(); iIndex1++)
        {
            cout << StripNonAlnum (cTokens[iIndex1]) << '\n';
        }
    }

    -- 
    Jon Bell <jtbellap8@presby.edu>                     Presbyterian College
    Dept. of Physics and Computer Science        Clinton, South Carolina USA
    

  • Next message: Perry St-Germain: "C++ and persistent objects"

    Relevant Pages

    • Re: Get the path and namefile in run time
      ... function Get_Path_Only return String; ... -- This returns the first N characters of the program name. ... end loop; ...
      (comp.lang.ada)
    • Re: Parse String
      ... it picking up substrings beginning with 'f' followed by hyphens, ... Function gnaf(s As String) As Variant ... Exit Do 'inner Do ... Loop ...
      (microsoft.public.excel.programming)
    • Avoiding side effects
      ... function Strip (Remove_This: in String) return String ... The main program is then merely a loop where I alternate between ... exit when EOF_Reached; ...
      (comp.lang.ada)
    • Re: Ada Shootout program for K-Nucleotide (patches)
      ... - a loop reading input lines into an ... ubounded string replaces the recursive String "&"ing ... The following Getline has left me unconvinced. ... exit when Last = Item'Last; ...
      (comp.lang.ada)
    • Re: new line character in a string
      ... is there any other mechanism to use newline character in a PS string? ... {%loop over file ... dup currentfile exch readstring exch ...
      (comp.lang.postscript)