quick and hopefully easy c++question

Discussion in 'OT Technology' started by MP, Oct 1, 2004.

  1. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    I'm not sure how to read a complete line and have it read specific commands as it goes.

    example

    instert 1/4 530-555-1234


    i've been trying to use getline but it doesn't seem to work :squint:

    month/day are ints, and the phone number is a string, insert is the command it needs to do.

    I can do it when it's on seperate lines. That's easy but all on the same line??? any suggestions ??

    thanks
     
  2. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán
    Parse it. Each line consists of a command followed by some parameters, all separated by whitespace? All you need to do is break up the line into it's components and it's as if they were read from separate lines. I suggest you look up the methods of std::string, paying close attention to find, find_first_of and substr.
     
  3. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    yea...I was looking on google (std:string) for like an hour before I asked. I couldn't figure out how to make it all on one line. Most of the examples were seperated by multiple lines.
     
  4. EkriirkE

    EkriirkE Zika Xenu OT Supporter

    Joined:
    Jan 11, 2004
    Messages:
    14,799
    Likes Received:
    0
    Location:
    Dublin & San Francisco, CA
    do something along the lines of

    Code:
    firstspace=0;
    while (firstspace<strlength) {
    while (str[firstspace]==' ' && firstspace<strlength) firstspace++; //skip whitespace
    if (lastspace>=strlength) break; //mem access protection
    lastspace=firstspace;
    while (str[lastspace]!=' ' && lastspace<strlength) lastspace++; //find end of word
    if (lastspace>=strlength) break;
     
    memcopy(thestring,str[firstspace],lastspace-firstspace); //copy segment(word) to new location
    thestring[lastspace-firstspace]=0; //null terminate
     
    DoSomethingWith(thestring);
     
     
    firstspace=lastspace;
    };
    
     
  5. SL1200MK4

    SL1200MK4 New Member

    Joined:
    Sep 27, 2003
    Messages:
    1,552
    Likes Received:
    0
    fscanf would do the trick easily if you are in C

    However people shouldn't those functions that's dangerous in nature anymore...
     
  6. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    any chance i could get a little more explination on this? I don't really understand still how to have multiple commands on one line, not just strings but a combination of ints' strings & cmd's.

    thanks
     
  7. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán
    That code basically does what find_first_of() and substr() would do.

    What you need to do is:

    1) Break up the line into substrings. In the example you gave, you want to end up with strings that contain "insert", "1/4", "530-555-1234"

    2) Further parse the substrings if needed. If "1/4" represents a month and day, then you want to break that up into strings that contain "1" and "4", then you can use atoi() to convert those strings to integer values.

    Once you have the entire line in a std::string, you can parse it quite easily using std::string::find_first_of() and std::string::substr().
     
  8. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    okay so i have to take in the line a a bunch of strings

    then after that convert the strings into the ints / commands / strings etc.. ?

    I think that's the part I was confused about.

    google time :hs:
     
  9. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    :wtc:


    edit: still don't get how to do it. Nothing on google is really helping me

    :sadwavey:
     
    Last edited: Oct 5, 2004
  10. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán
    Since you mentioned getline() in the first post, I've been assuming you want to read a whole line at once. Is that correct?

    If you do this:

    std::string line;
    std::string::getline(cin, line);

    and the user inputs the example you gave, line will contain the string "insert 1/4 530-555-1234" after the user hits the enter key. Then it's you're job to break up the string into substrings and do whatever other parsing is necessary.

    If you we're to do this:

    char cmd[256];
    char date[256];
    char tel[256];

    cin >> cmd;
    cin >> date;
    cin >> tel;

    or

    std::string cmd;
    std::string date
    std::string tel;

    std::string::getline(cin, cmd, ' ');
    std::string::getline(cin, date, ' ');
    std::string::getline(cin, tel, ' ');

    The user still enters the example as one line, but this way automatically breaks up the line based on whitespace.
     
  11. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    god damn this is confusing

    edit: how is that turning the date into an int?
     
  12. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán
    Nothing is being converted into an int. What exactly is confusing?
     
  13. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    i think because i've never done it before it's confusing me. It's like i'm not sure where to start for getting it to work.

    thanks for your help though. You rock!
     
  14. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    i know i'm probably reallly dumb for posting this because i'm sure it's so off you'll laugh at me but...

    Code:
    
    #include <iostream>
    #include <string>
    #include <sstream>
    using namespace std;
    
    class bill
    {
        // Setting the field variables
        int month, day;
        string phone;
        int minutes;
      
        public:
        // Define the constructors
        bill()  					{ month = 0; day = 0; phone = ""; minutes = 0; }
        bill(int m_month, int m_day, int m_minutes)	{ month = m_month; day = m_day; minutes = m_minutes;}
        bill(string m_phone)			{ phone = m_phone; }
           
        // Define the mutators
        void setmonth(int m_month)		{ month = m_month; }
        void setday(int m_day)		{ day = m_day; }
        void setphone(string m_phone)	{ phone = m_phone; }
        void setminutes(int m_minutes)	{ minutes = m_minutes; }
        
        //Define the accessors...
        int getmonth()			{ return month; }
        int getday()			{ return day; }
        string getphone()	 		{ return phone; }
        int getminutes()			{ return minutes; }
        
    };  
       
    // Declare the functions
    void readIn()
    void insert(bill, bill[], int&);
    void remove(string, bill[], int);
    bill lookup(string, bill[], int);
    void print(bill[], int);
    
    int main()
    {
       int currsize = 0;
       int m_month, m_day;
       string cmd, m_phone;
       int m_minutes;
       
       bill tempname;
       bill list[20];
       
       //This is the main processor loop that drives the operation
       //of the program...
       
       for( ; ; ) 
        {
            getline(cin, cmd);
         
            if(cmd == "exit")
            break;
            else if(cmd == "insert")
        {
        
        void readIn()
        {
            string line;
            string insert;
            
            int i = 0
            
            while(line[i] != ' ')
            {
                insert[i] = line[i]
                i++;
            }
            i++;
            
            int monthIterator = 0;
            while(line[i] != '/')
            {
                month[m_month] = line[i];
                monthIterator++;
                i++;
            }
            i++;
            
            m_month = atoi (month.c_str ());
            
            int dayIterator = 0;
            while(line[i] != ' ')
            {
                day[dayIterator] = line[i];
                dayIterator++;
                i++;
            }
            i++;
            m_day = atoi(day.c_str ());
    
    

    am i getting closer?
     
  15. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán
    Your code looks messed up or incomplete.

    Here's how find_first_of works:

    let's take a string:

    Code:
    string line = "insert 1/4 530-555-1234";
    
    find_first_of takes many forms with regard to its arguments, but the one we're
    most interested in is the one that searches for a character starting at the beginning
    of the string.

    Code:
    int n = line.find_first_of(" \t");
    
    That call to find_first_of is asking for the first occurence of either a space or tab
    character in the string line. If it finds a space or tab, it will return the index at which
    the first character is found. If the string doesn't contain any spaces or tabs, it will
    return the value string::npos. Given the example, it should return 6 since the first
    space occurs at position 6.

    So, now that we know where the first space is, we can extract the first substring.

    Code:
    string s1 = line.substr(0, n);
    
    The call to substr asks for a substring of the string line starting at character 0 with
    length n. The result we get is the string "insert" assigned to string s1.

    Now, look for the next space:

    Code:
    int placeholder = n+1;
    n = line.find_first_of(" \t", placeholder);
    
    This time we're asking for the search to begin at position n+1, because find_first_of would return the position of the first space again if we started from the beginning.
    If the search was successful, we will have the index of the next space, and we can
    now extract the next substring.

    Code:
    string s2 = line.substr(placeholder, n-placeholder);
    
    And so forth, until no more spaces are found.
    Hope that helps.
     
  16. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    yea, i am understanding the concept I just don't know how to implement it into my code really. :\
     
  17. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    here is my complete code. Maybe it will make more sense

    Code:
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <cstdlib>
    using namespace std;
    
    class bill
    {
        // Setting the field variables
        int month, day;
        string phone;
        int minutes;
      
        public:
        // Define the constructors
        bill()  					{ month = 0; day = 0; phone = ""; minutes = 0; }
        bill(int m_month, int m_day, int m_minutes)	{ month = m_month; day = m_day; minutes = m_minutes;}
        bill(string m_phone)			{ phone = m_phone; }
           
        // Define the mutators
        void setmonth(int m_month)		{ month = m_month; }
        void setday(int m_day)		{ day = m_day; }
        void setphone(string m_phone)	{ phone = m_phone; }
        void setminutes(int m_minutes)	{ minutes = m_minutes; }
        
        //Define the accessors...
        int getmonth()			{ return month; }
        int getday()			{ return day; }
        string getphone()	 		{ return phone; }
        int getminutes()			{ return minutes; }
        
    };  
       
    // Declare the functions
    void insert(bill, bill[], int&);
    void remove(int, int, string, bill[], int);
    bill lookup(int, int, string, bill[], int);
    void print(bill[], int);
    
    void readIn()
    {
        string line;
        getline(cin, line);
        
        int i = 0;
        int k = 0;
        
        string str_month, str_day, str_minutes;
        
        while(line[i] != '')
        {
            str_month[k] = line[i];
            k++;
            i++;
        }
        i++;
        
        while(line[i] != '/')
        {
            str_month[k] = line[i];
            k++;
            i++;
        }
        i++;
    }
    
    
    
    int main()
    {
        bill myArray;
        bool test = false;
        
        while (true)
        {
            test = readIn();
            
            if (test == false) return 0;
        }
    
    }
    
    
    
    bool readIn()
    {
        string line, m_month, m_day, m_phone;
        int minutes;
        
        int intMonth, intDay;
        
        string action;
        
        getline(cin, line);
        
        if(action == "insert")
        { insert(intMonth, intDay, m_phone, minutes); }
        
        { return false; }
        
        return true;
    }
    
    
    //insert() will allow the user to put a new value on the list.
    void insert(bill newname, bill namelist[], int& currsize)
    {
        if(currsize < 20) 
        {
            namelist[currsize] = newname;  //put the name on the end...
            currsize++;
        }
        else
        cout << "Sorry, List is full!" << endl;
    }
    
    
    
    //remove() marks a specific location in the array as empty
    void remove(int keymonth, int keyday, string keyphone, bill namelist[], int currsize)
    {
        int k;
        bill nullname;
        
        for(k = 0 ; k < currsize ; k++)
        if(keymonth == namelist[k].getmonth() && keyday == namelist[k].getday() && keyphone == namelist[k].getphone())  
        {
              cout << "removing " << keyphone << " at location " << k << endl;
              namelist[k] = nullname;
        }
    }
    
    
    //lookup() allows the user to look for a specific name on the list.
    //It returns the value if there's a match.
    //It returns a suitable error message if there is not match...
    bill lookup(int keymonth, int keyday, string keyphone, bill namelist[], int currsize)
    {
        int k;
        bill nullname;
       
        for(k = 0 ; k < currsize ; k++)
        if(keymonth == namelist[k].getmonth() && keyday == namelist[k].getday() && keyphone == namelist[k].getphone())
        {
        cout << namelist[k].getmonth() << "/";
        cout << namelist[k].getday() << ": ";
        cout << namelist[k].getphone();
        cout << " " << namelist[k].getminutes() << endl;
        }
        
        return nullname;          			//if the program is here, 
    }                                               //there was no match...
    
    
    //print() will display all the names on the list.
    void print(bill namelist[], int currsize)
    {
        int k;
       
        for(k = 0 ; k < currsize ; k++)
        if(namelist[k].getphone() != "") 
        {
            cout << namelist[k].getmonth() << "/" ;
            cout << namelist[k].getday() << ": ";
            cout << namelist[k].getphone(); 
            cout << " " << namelist[k].getminutes() << endl;
        }
    }
    
    
    that's my first attempt at trying to get it on one line...it's obviously really messed up :wtc: if i could just figure out how to get it all on one line i'de pretty much be done with this damn thing!! :(
     
  18. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán
    Code:
    bool readIn()
    {
        string line, m_month, m_day, m_phone;
        int minutes;
        
        int intMonth, intDay;
        
        string action;
        
        getline(cin, line);
    
    Well, that's at least the beginning looks ok. If the user types "insert 1/4 530-555-1234" and hits the enter key, line will now contain the string "insert 1/4 530-555-1234". Now go back and look at my previous post. Extract the first substring.

    Code:
         int n = line.find_first_of(" ");
         if (n != string::npos)
         {
              action = line.substr(0, n);
         }
         else
         {
              return false;
         }
    
    So, action now contains the string "insert". You'll probably want to handle the rest of the line differently based on the action, since different actions take different parameters. The rest I'll let you code. I've given you comments to help you out.

    Code:
        if(action == "insert")
        {
             // extract the "mm/dd" date substring
    
             // parse "mm/dd" to extract "mm" and "dd" and convert those to ints
    
             // extract the phone number string
    
             // extract the minutes string and convert to int
    
             insert(intMonth, intDay, m_phone, minutes);
        }
        else if (action == ????)
        {
        }
        else if (action == ????)
        {
        }
        else
        { return false; }
        
        return true;
    }
    
     
  19. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    so is my void readIn okay?

    and that bottom code you posted would go in my int main() right? or does it get included in bool readIn? i still don't understand how to convert the stuff to ints. :\

    edit: also, can you explain how to parse stuff??? i dunno what that is
    edit.2: how should i declare my readIn? is it still void readIn?

    do you have a working example of this I could see? I think if i were to see it I could implement it much easyer. It's still not even close to working because i'm not sure where i'm supposed to put anything.
     
    Last edited: Oct 6, 2004
  20. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley

    when i tried to include those things it automatically quits the program. Should it still let me type in something with just that? I'de like to at least be able to do that before i move onto all the other stuff I don't understand.

    Code:
    bool readIn()
    {
        string line, m_month, m_day, m_phone;
        int minutes;
        int currsize = 0;
        bill tempname;
        bill list[20];
        
        int intMonth, intDay;
        
        string action;
        
        getline(cin, line);
        
        int n = line.find_first_of(" ");
        if (n != string::npos)
        { action = line.substr(0, n); }
        else
        { return false; }
        
        if(action == "insert")
            {
                string s1 = line.substr(0, n);
                
                int placeholder = n+1;
                n = line.find_first_of(" \t", placeholder);
                
                string s2 = line.substr(0, n);
                
                int placeholder1 = n+2;
                n = line.find_first_of(" \t", placeholder1);
    
                insert(tempname, list, currsize);
            }
        else
        { return false; }
        
                
    }
    arrrrgggg :wtc:
     
    Last edited: Oct 6, 2004
  21. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán
    You're heading in the right direction, but please read my post regarding the use of find_first_of() and substr() again. It seems you still don't understand how to use them correctly.

    The arguments to those methods look like this:

    int string::find_first_of(string chars_to_search_for, int index_at_which_to_begin_search)

    string string::substr(int index_to_beginning_of_substring, int length_of_substring)

    In your calls to substr, why are you always starting at index 0?

    With regard to converting strings to ints, aren't you familiar with atoi()?
    In one of the bits of code you posted, you have the line:

    m_month = atoi (month.c_str ());

    Do you not know what that does?
     
  22. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    i tried reading over it but I just don't get where or what i'm supposed to put. I'll keep trying.

    i don't know where i'm supposed to put the int string::find_first_of (....) or what i'm supposed to put in it.

    I also don't know what i've done right or wrong

    you do know post #17 was my complete code right?
     
    Last edited: Oct 6, 2004
  23. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    i was just playing around with that. I really have no idea how it works

    there's no complete example online for this process? because i'm not really make much process in getting it to work i think.
     
    Last edited: Oct 6, 2004
  24. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán
    Don't you have any C/C++ reference books or online references?

    int atoi(char *str);

    You give atoi a pointer to a null-terminated string (char array) containing a text representation of a number, and it will return the integer value of that number.

    eg.

    char *p = "1234";
    int n = atoi(p);

    n will now equal 1234.

    In order to get atoi to work with a std::string, you need to get a null-terminated char array version of the string, and that's what std::string::c_str() gives you.

    eg.

    string str = "1234";
    int n = atoi(str.c_str());
     
  25. MP

    MP New Member

    Joined:
    Sep 10, 2002
    Messages:
    34,377
    Likes Received:
    0
    Location:
    Silicon Valley
    oh i'm really not that worried about that. I'm more worried about getting the complete line thing to work. I'll worry about converting it later or something...I still haven't made any progress getting the readIn things to work. my book says nothing about this type of stuff (what i'm having problems figuring out). You don't have any other suggestions?
     

Share This Page