Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C++: need help tracking array positions

  1. Feb 12, 2005 #1

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    I believe I am stuck. :frown: I need to traverse an array which will contain a sentence the user enters and identify the array positions of the first and last letters of each word in the sentence. I can do the first word, but I am not sure how to move it along after that. I am thinking I need to always store my last position of a previous word and use that when finding the first position of a new word but not sure how to do this. And I'm not sure how to move past the white spaces, but also stop at the end of the array. Thanks for any help.
    For an example - Desired output for sentence "my dog barks." would be:
    first letter array position: 0
    last letter array position: 1
    first letter array position: 3
    last letter array position: 5
    first letter array position: 7
    last letter array position: 11

    Code (Text):

    #include <iostream>
    using namespace std;

    int main()
    {
        char sentence[80];

        cout <<"Enter a sentence (no caps): \n";
        cin.getline(sentence,80);

        int i = 0;
        while (sentence[i] != '\0')
        {      
            if (sentence[i] <'a' || sentence[i] >'z')
            {          
                int last = i-1;
                int first = 0;
                cout << "first letter array position: " <<first <<endl;
                cout << "last letter array position: " <<last <<endl;          
            }
        i++;
               
        }
        return 0;  
    }
     
     
  2. jcsd
  3. Feb 12, 2005 #2

    plover

    User Avatar
    Homework Helper

    At any given time, the program needs to know whether or not it is currently processing a word. It also needs to know what to do when that state changes.

    How should the program tell that the state has changed? Well, if the current character is a letter, the state has changed if the previous character was not, and vice versa.

    So, each time through the loop there are basically two questions:
    1. Is the current character a letter, a non-letter, or null?
    2. Was the previous character a letter?
    So there are six possible cases to take care of.

    As an example, suppose the current character is a letter, and the previous one was not. That means we're at the beginning of a word. Thus (depending on how you want the program to work), you should either print the "first letter" message or store the position for future reference.

    Note that the different phrasing of the two questions is significant, and is a hint for dealing with the loop bounds (i.e. think about how the processing needs to deal with the first character of the array – which itself could be a letter or not).

    Also, note that when processing the end of the string it makes a difference whether the character prior to the null was a letter or not. Given the suggested input "my dog barks", the included code will only indicate two words.

    Minor quibble: for the included code as it stands, it would be more idiomatic to use a for-loop:
    for(int i=0; sentence != '\0'; ++i) { ...
     
    Last edited: Feb 12, 2005
  4. Feb 12, 2005 #3

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    hi plover, I made some progress since my last post. I still have to work out dealing with that null character at the end. Do you think this approach is any better?

    Code (Text):

    #include <iostream>
    using namespace std;

    int main()
    {

        char sentence[80];

        cout <<"Enter a sentence (no caps): \n";
        cin.getline(sentence,80);

        int first, last;
        int i = 0;
        bool flag = 0;
        while (sentence[i] != '\0')
        {
           

        if ((sentence[i] >='a' && sentence[i] <='z') && (flag == 0))//is letter and we're looking for a letter
        {
            first = i;
            flag = 1;
            i++;
        }

        else if ((sentence[i] >='a' && sentence[i] <='z') && (flag == 1))//is letter but we're looking for 'non-letter'
        {
            i++;
        }

        else if ((sentence[i] <'a' || sentence[i] >'z') && (flag == 1)) //is non-letter and we're looking for non-letter
        {  
            last = i-1;
            cout << "first letter array position: " <<first <<endl;
            cout << "last letter array position: " <<last <<endl;  
            flag = 0;
            i++;
        }
       
        else //it's non-letter but we're looking for letter
        {
            i++;
        }
               
        }

        return 0;
       
    }
     
  5. Feb 12, 2005 #4

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member


    I'm just trying to follow my teacher's examples here. He actually had some reason for not using a for loop in some of the related examples - I remember because somebody asked him about it - it was something about the "complexity of the conditional" I think he said. I can't remember exactly. I think he just didn't want to confuse us since we're beginners.
     
  6. Feb 12, 2005 #5

    dduardo

    User Avatar
    Staff Emeritus

    Why don't you try this:

    Code (Text):

    #include <iostream>
    using namespace std ;

    int main( int argc, char **argv ) {

        char sentence[80] ;
        bool first = true ;

        cout << "Enter a sentence (no caps):" << endl;
        cin.getline( sentence,80 ) ;
       
        for( int i=0; sentence[i] != '\0'; i++ ){
            if( first && sentence[i] >= 'a' && sentence[i] <= 'z' ) {
                cout << "First letter array position: " << i << endl ;
                first = false ;
            } else if ( !first && (sentence[i] < 'a' || sentence[i] > 'z') ){
                cout << "Last letter array position: " << i-1 << endl ;
                first = true ;
            }
        }
                   
        return 0 ;
    }
     
     
  7. Feb 12, 2005 #6

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    hey dd - thanks! but what are those arguments in main()?
     
  8. Feb 12, 2005 #7

    dduardo

    User Avatar
    Staff Emeritus

    Those are for the command line. You don't have to have them if you don't want. It will be assumed void if you don't put any main arguments.
     
  9. Feb 12, 2005 #8

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    ah, ok. Thanks. I have this vague memory of them from a C class I took now.
     
  10. Feb 12, 2005 #9

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    I just thought of a question I've been wondering about. Can you pass an array into a function, do stuff to it, and pass it back out again? thx.
     
  11. Feb 12, 2005 #10

    dduardo

    User Avatar
    Staff Emeritus

    Arrays, by default, are passed by reference to functions. Therefore, if you have a function with parameters like this

    int myfunction( int *array ) { /*code*/ }

    Then you can do something like this:

    int array[3] ;

    myfunction(array) ;

    The base address is passed onto myfunction and you can manipulate the array to your hearts content. There is no need to return the array back because your addressing the memory directly.
     
  12. Feb 12, 2005 #11

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    thanks. I wasn't sure what I could do. Our TA mentioned manipulating the array inside a function, but the teacher hasn't lectured on this yet, so I wasn't sure if it was the same method as in C programming or something different.
     
  13. Feb 12, 2005 #12

    plover

    User Avatar
    Homework Helper

    The problem is that the null character can't be treated specially until after it's been processed. This can be done with a do-while-loop or by using a break statement.

    This was my version:
    Code (Text):
    #include <iostream>
    using namespace std ;

    int main() {

        char sentence[80] ;

        cout << "Enter a sentence (no caps):" << endl;
        cin.getline( sentence,80 ) ;

        for(int first=-1, pos=0; ; ++pos) {
            bool letter = (sentence[pos] >= 'a' && sentence[pos] <= 'z');
            if(first < 0) {
                if(letter) first = pos;
            } else {
                if(!letter) {
                    cout << "first letter array position: " << first << endl;
                    cout << "last letter array position: " << (pos-1) << endl;
                    first = -1;
                }
            }
            if(sentence[pos] == '\0') break;
        }
        return 0 ;
    }
     
    Yes, passing an array to a function works by passing the address of the first array element. Thus, operations on the elements of the array will be persistent when the function returns (no need to return the pointer). Also, remember from C that the contents of the address referred to by a pointer can be accessed like an array.

    So if a function is declared like this:
    void messWithString(char* aString);
    It can be used like this:
    char someText[] = "yadda yadda yadda";
    messWithString(someText);

     
  14. Feb 12, 2005 #13

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    thanks, plover. I always get really confused on anything that is pass-by-reference or anything involving pointers. I don't think I ever learned it very well. I better go make some simple examples of "messwithstring" functions and see what I can do.
    Your program is really great - it catches all the first and last letters!! - but it will take me a while to understand how it works.
    A question I have about:
    for(int first=-1, pos=0; ; ++pos)
    why is there an empty space between the ; ; where you would normally put a condition?
     
  15. Feb 13, 2005 #14

    plover

    User Avatar
    Homework Helper

    All three clauses of the for-loop mechanism are optional, but the two semi-colons are required. There's no good way to put the condition at the top of the for loop that will allow the loop to be executed for the case of the current character being the terminal null, so I just left it out. The loop could also be:
    int first=-1, pos=0;
    do { ... } while(sentence[pos++] == '\0');
    but this does not restrict the scope of first and pos to the loop.

    Also, while it's arranged a little differently, the logic of the if-statements inside the loop in my version is actually nearly identical to that of dduardo's version.
     
  16. Feb 13, 2005 #15

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    I knew that in this case that the string would be limited to 80 chars, so I ended up just doing this:
    for( int i=0; i<80; i++ )

    and then breaking if '\0' is encountered.
    I guess that's OK..?? I had tried a do while loop first but didn't have much luck.

    Oh, and I worked out some functions that manipulate the string - worked great!

    tahkns for yuor hlep :smile:
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?



Similar Discussions: C++: need help tracking array positions
  1. Need help (Replies: 5)

  2. Need help! (Replies: 10)

Loading...