ok_
ok_

Reputation: 101

Beginner difficulty with vectors and while-loops in C++

Update:

So it turns out there were two issues:

The first is that I checked the [k-1] index before I checked k == 0. This was a crash, although mostly fixable, and not the primary issue I posted about.

The primary issue is that the code seems to execute only after I press ctrl+z. Not sure why that would be.

Original:

So, learning from Stroustrup's text in C++ programming, I got to an example on vectors and tried implementing it myself. The gist is that the program user enters a bunch of words, and the program alphabetizes them, and then prints them without repeats. I managed to get working code using a for statement, but one of my initial attempts confuses me as to why this one doesn't work.

To be clear, I'm not asking to improve this code. I already have better, working code. I'm wondering here why the code below doesn't work.

The "error" I get is that the code compiles and runs fine, but when I input words, nothing happens and I'm prompted to input more.

I'm certain there's an obvious mistake, but I've been looking everywhere for the last 8 hours (no exaggeration) just devoted to finding the error on my own. But I can't.

int main() {
    vector<string> warray; string wentry; int k = 0;
    cout << "Enter words and I'll alphabetize and delete repeats:\n\n";
    while (cin >> wentry) warray.push_back(wentry);
    sort(warray.begin(), warray.end());
    while (k < warray.size()) {
    if (warray[k - 1] != warray[k] || k == 0) cout << warray[k] << "\n";
    ++k;
    }
}

My reasoning for why this should work is this: I initialize my array of words, my word entry per input, and a variable to index word output.

Then I have a while statement so that every input is stacked at the end of the array.

Then I sort my array.

Then I use my index which starts at 0 to output the 0th item of the array.

Then so long as there are words in the array not yet reached by the index, the index will check that the word is not a repeat of the prior index position, and then print if not.

No matter what whappens, the index is incremented by one, and the check begins again.

Words are printed until the index runs through and checks all the words in the array.

Then we wait for new entries, although this gets kind of screwy with the above code, since the sorting is done before the checking. This is explicitly not my concern, however. I only intend for this to work once.

Upvotes: 0

Views: 909

Answers (4)

shauryachats
shauryachats

Reputation: 10385

You just needed to reverse:

if (warray[k - 1] != warray[k] || k == 0)

to

if (k == 0 || warray[k - 1] != warray[k] )

for terminating this condition if k = 0.

An alternative.

Although it can termed as a bit off topic, considering you want to work with std::vector<>, but std::set<> is an excellent container which satisfies your current two conditions:

  1. Sort the strings in alphabetical order.
  2. Delete all the repetitions.

Include <set> in your .cpp file, and create a set object, insert all the std::string and iterate through the set to get your ordered, duplicate-free strings!

The code:

int main() {
   //Define a set container.
   set<string> s;
   //A temporary string variable.
   string temp;
   //Inserting strings into the set.
   while (cin >> temp) s.insert(temp);
   //Create a set<int> iterator.
   set<string>::iterator it;
   //Scanning the set
   for(it = s.begin(); it != s.end(); ++it)
   {
     //To access the element pointed by the iterator,
     //use *it.
     cout<<*it<<endl;
   }
   return 0;
}

I just recommended this container, because you will study set in Stroustrup's text, and it is very easy and convenient instead of laboring over a vector.

Upvotes: 0

Cryptopone
Cryptopone

Reputation: 31

You're stuck in the while loop because you don't have a way of breaking out of it. That being said, you can use Ctrl + d (or use Ctrl + z if executing on windows in the command prompt) to break out of the loop and continue executing the code.

As for while loop at the bottom which prints out the sorted vector of values, your program is going to crash as user902384 suggested because your program will first check for warray[k - 1].

Ideally, you want to change the last part of your program to:

while (k < warray.size()) 
{
    if (k == 0 || warray[k - 1] != warray[k]) 
        cout << warray[k] << "\n";
    ++k;
}

This way, the k == 0 check passes and your program will skip checking warray[k - 1] != warray[k] (which would equal warray[-1] != warray[0] when k=0).

Upvotes: 0

nothingness
nothingness

Reputation: 31

At the point where you take

warray[k - 1]

for the first time, k is zero, so you want to get the warray value at index -1, which is not necessarily defined in memory (and even if, I wouldn't do this anyway). So as it compiles, I guess the address is defined in your case by accident.

I would try simply reversing the OR combination in your if-condition:

 if (k == 0 || warray[k - 1] != warray[k])

thus for the first iteration (k == 0) it won't check the second condition because the first condition is then already fulfilled.

Does it work then?

Upvotes: 2

shiv
shiv

Reputation: 1952

To end the cycle of input you need to insert EOF character which is ctrl+d. However, there are other problems in your code. You have k = 0 to start with so the moment you will try warray[k - 1] your code will crash.

Upvotes: 2

Related Questions