How to Track Array Positions of Words in a C++ Sentence?

  • Context: C/C++ 
  • Thread starter Thread starter Math Is Hard
  • Start date Start date
  • Tags Tags
    Array Tracking
Click For Summary

Discussion Overview

The discussion revolves around the problem of traversing an array in C++ to identify the positions of the first and last letters of each word in a user-inputted sentence. Participants explore various coding approaches, logic for handling word boundaries, and the implications of different loop structures.

Discussion Character

  • Technical explanation
  • Exploratory
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant expresses difficulty in moving past whitespace and tracking the last position of a word while traversing the array.
  • Another participant suggests that the program should maintain a state to determine if it is currently processing a word, proposing a method to handle state changes based on the character type.
  • A different approach is presented that uses a flag to indicate whether the current character is part of a word, with specific conditions to identify the first and last letters of words.
  • One participant questions the use of a for-loop versus a while-loop, citing a teacher's reasoning related to complexity in conditionals.
  • Another participant shares a simplified version of the code that effectively identifies word boundaries using a boolean flag.
  • There is a discussion about passing arrays to functions in C++, with clarification that arrays are passed by reference, allowing for manipulation within functions without needing to return them.
  • A participant raises a concern about handling the null character at the end of the string, suggesting alternative loop structures to address this issue.

Areas of Agreement / Disagreement

Participants present multiple competing views on how to effectively traverse the array and handle word boundaries. There is no consensus on a single approach, as various methods are proposed and discussed.

Contextual Notes

Some participants mention limitations related to handling the null character and the complexity of conditionals in loop structures. There are also references to educational contexts that may influence coding style choices.

Who May Find This Useful

This discussion may be useful for individuals learning C++ programming, particularly those interested in string manipulation, array handling, and understanding function parameter passing.

Math Is Hard
Staff Emeritus
Science Advisor
Gold Member
Messages
4,663
Reaction score
36
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:
#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;	
}
 
Technology news on Phys.org
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:
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:
#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;
	
}
 
plover said:
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) { ...

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.
 
Why don't you try this:

Code:
#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 ;
}
 
hey dd - thanks! but what are those arguments in main()?
 
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.
 
ah, ok. Thanks. I have this vague memory of them from a C class I took now.
 
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.
 
  • #10
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.
 
  • #11
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.
 
  • #12
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:
#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 ;
}
Math Is Hard said:
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.
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);
 
  • #13
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?
 
  • #14
Math Is Hard said:
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?
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.
 
  • #15
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:
 

Similar threads

  • · Replies 25 ·
Replies
25
Views
3K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 23 ·
Replies
23
Views
2K
Replies
20
Views
3K
  • · Replies 15 ·
Replies
15
Views
5K
Replies
12
Views
3K
Replies
12
Views
2K
  • · Replies 31 ·
2
Replies
31
Views
3K