3

I was trying to go to the end of the string, go back until the last space, then go forward until the end of the word and store that word in an empty string. No arrays or pointers are allowed.

string getLastWord(string text)
{
    string lastword="";
    int last=text.size()- 1;
    int beginlast=0;
    if text == "";
    return  "";
    for (int i=last; i>=1; i--)
    {
        if (isspace(text[i]))
            beginlast=beginlast+i;
    }
    for (int k=0; k!=text.size; k++)
    {
        if (isalpha(text[k]))
            lastword=lastword+lastword[k];
    }
    return lastword;
}
Kurt Stutsman
  • 3,994
  • 17
  • 23
user1007658
  • 39
  • 1
  • 1
  • 2

5 Answers5

10

have you looked at the function

string.find_last_of( ' ' );

?

EDIT: Ok I see now there are new requirements, try then this (you should do some error checking like if you do not find a space)

#include <iostream>
using namespace std;

int main() {
    string text{"my big and long string"};
    // find last space, counting from backwards
    int i = text.length() - 1; // last character
    while (i != 0 && !isspace(text[i]))
    {
      --i;
    }
    string lastword = text.substr(i+1); // +1 to skip leading space
    cout << lastword << endl;
    return 0;
}
AndersK
  • 35,813
  • 6
  • 60
  • 86
1

The method from 'AndersK' is quite good. But what if you have empty characters at the end of the string: string text{" my big and long string "}; ? The code doesn't return any last word.

So I was thinnking... - why not to check the last character with the same means it is already used. And then to go character by character backwards until you find the character of the last word. And then go backwards with already written code by someone. So I fulfilled this code block and made a function:

string Last_str_word(const string& text)
{
    int i = text.length() - 1;
    
    if (isspace(text[i]))
        while (isspace(text[i])) i--;
    
    while (i != 0 && !isspace(text[i])) --i;
    
    string lastword = text.substr(i + 1);
    return lastword;
}

It works and you don't have to worry if there are empty characters at the end. It will still return the last word.

Tomasm21
  • 11
  • 1
1

Maybe something like this. We trim away spaces from the end first. If you want to consider other types if ignorable whitespace, you can extend this trivially.

std::string input; // your data

std::size_t pos = input.size();
while (input[pos] == ' ' && pos > 0) --pos;

if (pos == 0) { /* string consists entirely of spaces */ }

std::string result = input.substr(input.find_last_of(' ', pos));

To do it manually:

std::string input; // your data
std::size_t pos = input.size();
while (input[pos] == ' ' && pos > 0) --pos;

if (pos == 0) { /* string consists entirely of spaces */ }

const std::size_t pos_end = pos;
while (input[pos] == ' ' && pos > 0) --pos;

std::string result = input.substr(pos, pos_end - pos);
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • `std::size_t pos = input.size(); while (input[pos]` -- isn't it an overrun in the first iteration? – vines Aug 11 '20 at 12:55
0
#include <iostream>
#include <string.h>

using namespace std;

int main()
{
    int l, d, i;
    char a[100];
    cout << "Enter the string: " << endl;
    gets(a);
    l = strlen(a);

    for (i = 0; a[i] != 0; i++)
    {
        if (a[i] == ' ')
            d = i;
    }

    cout << endl;
    cout << "The last word of the string:"
    for (i = d + 1; a[i] != 0; i++)
    {
       cout << a[i];
    }

    return 0;
}
Chris
  • 26,361
  • 5
  • 21
  • 42
Marble
  • 125
  • 1
  • 9
  • i added this because the samething was given in my school and i liked it – Marble Mar 13 '18 at 15:55
  • Answers are typically more helpful when accompanied by some explanation of what they're doing and/r how they differ from the approach taken by the user asking the question or other answers posted. – Chris Oct 02 '21 at 07:53
  • Additionally worth mentioning that what you've posted is a hodgepodge of C and C++, and `gets` is particularly dangerous and its use discouraged. When writing C++ code there is no reason not to take advantage of C++. If you are going to use C strings, you should `#include ` rather than "string.h". – Chris Oct 02 '21 at 07:57
0

Just for variety's sake, let's try a reverse iterator to take away some of the drudge work of indexes. Then we'll account for spaces at the end of the string with a simple boolean flag found_nonspace. It starts out false.

Each time through the loop we examine the current character. If the flag is false, and it's a space, we use continue to move onto the next iteration. In this manner we can skip all trailing whitespaces.

As soon as it hits something that is not a space, we flip the flag to true and add that character to s1.

If the flag is true, then we've been going through the last word. If that's the case and we hit a space, then we break and the loop is done. We've got the entire last word in s1.

Finally, there's no need to check anything. At this point we know by process of elimination that we're in the last word, and it's still going on, so we add the current character to s1.

Of course, s1 will be the last word backwards, but as we're only accumulating it to return its length, that's irrelevant.

#include <iostream>
#include <string>

int lengthOfLastWord(string const& s);

int main() {
    std::string s;
    std::getline(std::cin, s);
    std::cout << lengthOfLastWord(s) << std::endl;
}

int lengthOfLastWord(string const& s) {
    bool found_nonspace = false;

    std::string s1;

    for (auto ch = s.rbegin(); ch != s.rend(); ch++) {
        if (!found_nonspace && std::isspace(*ch)) {
            continue;
        }
        else if (!found_nonspace) {
            found_nonspace = true;
            s1.push_back(*ch);
        }
        else if (found_nonspace && std::isspace(*ch)) {
            break;
        }
        else {
            s1.push_back(*ch);
        }
    }

    return s1.length();
}

In fact, if we really don't need to get the last word, but just its length, we needn't worry about s1 at all, and could just increment a length variable and then return it.

#include <iostream>
#include <string>

int lengthOfLastWord(string const& s);

int main() {
    std::string s;
    std::getline(std::cin, s);
    std::cout << lengthOfLastWord(s) << std::endl;
}

int lengthOfLastWord(string const& s) {
    bool found_nonspace = false;

    int len = 0;

    for (auto ch = s.rbegin(); ch != s.rend(); ch++) {
        if (!found_nonspace && std::isspace(*ch)) {
            continue;
        }
        else if (!found_nonspace) {
            found_nonspace = true;
            len += 1;
        }
        else if (found_nonspace && std::isspace(*ch)) {
            break;
        }
        else {
            len += 1;
        }
    }

    return len;
}

Let's really exercise iterators

We can actually make this a lot more terse, just by declaring our reverse_iterator outside of our loops. We'll use two loops. The first will reverse advance (from the end) the iterator through any spaces. This loop doesn't need a body.

Second, we'll basically do the same, but advance over any non-space characters, incrementing len as we go. Then we'll return len.

Also: we'll definitely want to check that we aren't trying to iterate too far by checking for ch != 2.rend().

int lengthOfLastWord(string const& s) {
    std::string::reverse_iterator ch = s.rbegin();
    int len = 0;

    for (; ch != s.rend() && std::isspace(*ch); ch++);
    for (; ch != s.rend() && !std::isspace(*ch); ch++, len++);

    return len;
}
Chris
  • 26,361
  • 5
  • 21
  • 42