0

I am missing the last word of string. this is code I used to store word into array.

string arr[10];
int Add_Count = 0;
string sentence = "I am unable to store last word"
string Words = "";
for (int i = 0; i < sentence.length(); i++)
{
    if (Sentence[i] == ' ')
    {
        arr[Add_Count] = Words;
        Words = "";
        Add_Count++;
    }
    else if (isalpha(Sentence[i]))
    {
        Words = Words + sentence[i];
    }
}

Let's print the arr:

for(int i =0; i<10; i++)
{
  cout << arr[i] << endl;
}
AbdelAziz AbdelLatef
  • 3,650
  • 6
  • 24
  • 52
Ishk
  • 21
  • 4

6 Answers6

0

You are inserting the word found when you see a blank character.

Since the end of the string is not a blank character, the insertion for the last word never happens.

What you can do is:

(1) If the current character is black, skip to the next character.

(2) See the next character of current character.

(2-1) If the next character is blank, insert the accumulated word.

(2-2) If the next character doesn't exist (end of the sentence), insert the accumulated word.

(2-3) If the next character is not blank, accumulate word.

Hyun I Kim
  • 589
  • 1
  • 3
  • 14
0

If you know you won't have to worry about punctuation, the easiest way to handle it is to throw the string into a istringstream. You can use the extraction operator overload to extract the "words". The extraction operator defaults to splitting on whitespace and automatically terminates at the end of the stream:

#include <algorithm>
#include <sstream>
#include <string>
#include <vector>

std::string sentence = // ... Get the string from cin, a file, or hard-code it here.
std::istringstream ss(sentence);

std::vector<std::string> arr;
arr.reserve(1 + std::count(std::cbegin(sentence), std::cend(sentence), ' '));
std::string word;
while(ss >> word) {
    arr.push_back(word);
}

Casey
  • 10,297
  • 11
  • 59
  • 88
  • 1
    `std::vector` instead of `std::array` makes much more sense... – David C. Rankin Oct 16 '20 at 04:18
  • @DavidC.Rankin Yeah, it does. Dunno what I was thinking. Also added pre-allocation since the size is no longer constant and dependent on the input string. – Casey Oct 16 '20 at 08:11
0

Obviously you lost the last word because when you go to the end the last word is not extracted yet. You can add this line to get the last word

if (Words.length() != 0) {
       arr[Add_Count] = Words;
       Words = "";
}
Che Huu
  • 163
  • 10
0

Following on from the very good approach by @Casey, but adding the use of std::vector instead of an array, allows you to break a line into as many words as may be included in it. Using the std::stringstream and extracting with >> allows a simple way to tokenize the sentence while ignoring leading, multiple included and trailing whitespace.

For example, you could do:

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

int main (void) {
    
    std::string sentence = "  I    am    unable to        store last  word    ",
                word {};
    std::stringstream ss (sentence);        /* create stringstream from sentence */
    std::vector<std::string> words {};      /* vector of strings to hold words */
    
    while (ss >> word)                      /* read word */
        words.push_back(word);              /* add word to vector */
    
    /* output original sentence */
    std::cout << "sentence: \"" << sentence << "\"\n\n";
    
    for (const auto& w : words)     /* output all words in vector */
        std::cout << w << '\n';
}

Example Use/Output

$ ./bin/tokenize_sentence_ss
sentence: "  I    am    unable to        store last  word    "

I
am
unable
to
store
last
word

If you need more fine-grained control, you can use std::string::find_first_of and std::string::find_first_not_of with a set of delimiters to work your way through a string finding the first character in a token with std::string::find_first_of and then skipping over delimiters to the start of the next token with std::string::find_first_not_of. That involves a bit more arithmetic, but is a more flexible alternative.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • It's even easier for custom delimiters! Just use `std::getline(ss, word, delim)` and all text between the delimiters will be grabbed. The only drawback is it will not skip "empty" strings resulting from a delimiter immediately preceeding itself, e.g. `"Hello,,World"` with a comma delimiter will result in `"Hello", "", "World"`. But this is easily prevented with a boolean check for "skipping empty". – Casey Oct 16 '20 at 09:28
0

This happens because the last word has no space after it, just add this line after for loop.

arr[Add_Count] = Words;
AbdelAziz AbdelLatef
  • 3,650
  • 6
  • 24
  • 52
0

My version :

#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

int main() {
  std::istringstream iss("I am unable to store last word");
  std::vector<std::string> v(std::istream_iterator<std::string>(iss), {});
  std::copy(v.begin(), v.end(),
            std::ostream_iterator<std::string>(std::cout, "\n"));
}

Sample Run :

I
am
unable
to
store
last
word
brc-dd
  • 10,788
  • 3
  • 47
  • 67
  • 1
    Wow. Three expressions. Learn the algorithms header, people!...Now I want to test your version against mine. :) – Casey Oct 16 '20 at 08:18