0

So, here's my code. I have to remove all 'a' and 'A' from the given text (which can be random) but here is the text block sample I'm given:

The quick brown fox jumps over a lazy dog. A cat ran away as the fox came around the bend. Further down the road, a student was ta- king an exam for his CS2433 class.

I've added a couple other cout's just to see along the way what's going on and it appears my cin is only taking in the "The" part of the given text to read in.

I'm not sure what's going on? The unix command I use to run the file with an input file is: ./hw5.out < hw5in.txt Should I use something different to pass in the string?

1 #include <iostream>
2 #include <algorithm>
3 using namespace std;
4
5 int main()
6 {
7
8    string str;
9    cin >> str;
10
11    char chars[] = "aA";
12    cout << str;
13    for (unsigned int i = 0; i < str.length(); i++)
14    {
15 
16
17       str.erase (std::remove(str.begin(), str.end(), chars[i]), str.end());
18    }
19    cout << str;
20    for (int i = 0; i < str.length();i++)
21    {
22       if (str[i] == '\n')
23       {
24          str[i] = '\t';
25       }
26    }
27
28 
29    cout << str;
30
31 }

UPDATE: I wrote out a while look with the getLine command concatenating each iteration into a variable "text" and then ran some of what my original code did, replacing all the str's with text. I appreciate the responses, I'll definitely being going through the repositories posted, thanks!

Kodie Hill
  • 21
  • 1
  • 6
  • You mean `operator>>`, but it's working fine. Your loop should be going to `chars.length()`, though, as you're going out of bounds now. – chris Oct 11 '12 at 03:14

4 Answers4

4

Thing is >> stops when reaching a blank. Maybe you want std::getline instead ?

std::getline(std::cin, str);
cnicutar
  • 178,505
  • 25
  • 365
  • 392
1

Extending @cnicutar's answer, here is the standard way of reading from std::cin,

std::string str;
while (std::getline(std::cin, str))
{
    // str now contains text upto the first newline
}

But if you are to remove all the 'a' and 'A', a better approach is to iterate through the input stream one character at a time.

std::cin >> std::noskipws; // Do not skip whitespaces in the input stream

std::istream_iterator<char> it(std::cin);
std::istream_iterator<char> end;

std::string result;

// Copy all characters except {'a', 'A') to result
std::copy_if(it, end, std::back_inserter(result),
                [](char c) -> bool { return c != 'a' && c != 'A'; }
                );
Hindol
  • 2,924
  • 2
  • 28
  • 41
0

To expand on the answer from @cnicutar and fix some other things in your code:

#include <iostream>
#include <algorithm>
#include <string>

int main()
{
    char* to_remove = "aA";

    while (!std::cin.eof())
    {
        std::string str;
        std::getline(std::cin, str);

        if (std::cin.fail())
        {
            std::cerr << "Error reading from STDIN" << std::endl;
            return 1;
        }


        size_t index = 0;

        while ((index = str.find_first_of(to_remove, index)) != string::npos)
        {
            str.erase(index);
        }

        std::cout << str << std::endl;
    }

    return 0;
}
Geoff Montee
  • 2,587
  • 13
  • 14
  • I suppose eof is end of file? So, that would pass in the entire text block. The rest of your changes are just defensive measures? – Kodie Hill Oct 11 '12 at 03:31
  • I wouldn't say defensive measures. As far as I could tell, the way you called `std::remove` was incorrect. Your calls to `std::string::erase` also look incorrect. You seem to have some unnecessary loops as well. – Geoff Montee Oct 11 '12 at 03:33
  • And yes, eof refers to end of file. You can view the std::istream documentation here: http://www.cplusplus.com/reference/iostream/istream/ – Geoff Montee Oct 11 '12 at 03:34
  • You can view the documentation for std::remove here: http://www.cplusplus.com/reference/algorithm/remove/ – Geoff Montee Oct 11 '12 at 03:36
  • This use of `std::remove` is also incorrect because `std::remove` by itself doesn't change the length of the string. That's why the [erase-remove idiom](http://stackoverflow.com/questions/6456870/stl-remove-doesnt-work-as-expected) exists. – Blastfurnace Oct 11 '12 at 03:37
  • Thanks for that bit of info @Blastfurnace. I changed that portion to something that makes a bit more sense to me. – Geoff Montee Oct 11 '12 at 03:47
  • I have to say this is the most helpful answer, just because of the eof instruction in a while loop. Thanks for the tips! – Kodie Hill Oct 11 '12 at 04:15
0

This is short and fairly simple. It shows one way to construct a std::string from an an input stream and the common erase-remove idiom.

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

bool is_aorA(char ch)
{
    return ch == 'a' || ch == 'A';
}

int main()
{
    std::istreambuf_iterator<char> input(std::cin), end;
    std::string str(input, end);

    str.erase(std::remove_if(str.begin(), str.end(), is_aorA), str.end());

    std::cout << str << '\n';
}

See it in action at ideone.com

Blastfurnace
  • 18,411
  • 56
  • 55
  • 70