Character I/O, and inputting spaces.

Pages: 123
Oct 19, 2012 at 1:07am
I just want a blank space.
Oct 19, 2012 at 5:59pm
These are the word for word instructions:

1
2
3
4
5
6
Allow the user to enter characters 
until the following requirements have been met:
1. Read a single non-whitepsace character
2. Read 5 space characters
3. Read a single non-whitepsace character
4. Output these 7 characters to the user


Console should look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
Enter a character followed by 5 spaces followed by a character:
1   3444  a
You entered:
1     a


Enter a character followed by 5 spaces followed by a character:
bcsa a

   d
 c
You entered:
b     c
Oct 19, 2012 at 6:03pm
This is seeming more and more like something you need to learn on your own. I've showed you how to ignore the 5 spaces, all you need to do is get this character after those spaces.

The second example is inherently impossible, the program would have stopped allowing you to enter characters after 'd' (as per my interpretation of the instructions).
Last edited on Oct 19, 2012 at 6:05pm
Oct 19, 2012 at 6:22pm
I don't know how to get the first and last character of whatever I've input..

And the second example doesn't seem impossible. Unless the 5 space requirement has been met, the program will keep asking you for input.

And every time I input anything with your code snippet, I'm getting nothing in return on the console.
Oct 19, 2012 at 6:35pm
Well, given the new examples, the termination condition cannot be '\n'.

The second example isn't impossible, inherently or otherwise.
Oct 19, 2012 at 7:05pm
All I want to know is how to extract the first and last character of anything I input :|
Oct 19, 2012 at 8:27pm
It's not so much of extracting the characters, it's spotting the.

Your code above handles the first char.
Adding code to count spaces is easy enough.
So all you've got to do is spot a non-space after 5 chars.

i.e.

 - while haven't found the last char
 - - is next char a space?
 - - yes: count it
 - - no : have their been 5 spaces? 
 - - - yes: display char and terminate loop
 - - - no : do nothing this time

Andy

PS As the word for word instructions don't make it clear how to handle (e.g.) 6 spaces?
"a______b" (where _ is a space) -> ? (an error?)
Last edited on Oct 19, 2012 at 8:31pm
Oct 19, 2012 at 8:41pm
Yeah, I'm not sure on the 5 spaces either. I'll probably make it display an error.

Anyway, regarding your pseudo-code: that's exactly where I'm stuck at. How do I display that very first while line?
while (input != last character)
How do I 'translate' the very last character of the input to be displayed?
Oct 19, 2012 at 8:56pm
How do I 'translate' the very last character of the input to be displayed?


I don't read it like that. I read it as the program ends after the first non-whitespace character after the 5 spaces: something like this:
1
2
3
4
5
6
7
8
char first, last;
cin >> first; // skips all white space until a character

//skip 5 spaces

cin >> last; // skips all whitespace until a character

cout << first << "     " << last << endl;
Last edited on Oct 19, 2012 at 8:58pm
Oct 19, 2012 at 9:07pm
Yeah, that's how I read it too except I'm not supposed to add the spaces in the
cout << first << " " << last << endl;
line myself. If I could do that, I wouldn't even have made this thread.

This is what should happen:
1
2
3
4
Enter a character followed by 5 spaces followed by a character:
84ad67b
You entered:
8     b


The program just ignores everything in between and outputs is as blank space.
Oct 20, 2012 at 1:50am
With a few tweaks, I could write this program. The difference is that it will only accepts characters on the first line and when enter is hit the program stores the line in a character array. Also, it will not jump to the next line to read characters, as in the example.

#include <iostream>
#include <fstream>
#include <cctype>

using namespace std;

char cChar[50];

void getChar(ofstream& out_stream);
void wait5Spaces(ofstream& out_stream);
void display(ifstream& in_stream);

int main()
{
ofstream out_stream;
out_stream.open("inFile.txt");
string sMyString;
cout << "Enter a character followed by 5 spaces, followed by a character: ";
getChar(out_stream);
wait5Spaces(out_stream);
out_stream.close();
ifstream in_stream;
in_stream.open("inFile.txt");
display(in_stream);
in_stream.close();
cout << endl;
return 0;
}

void getChar(ofstream& out_stream)
{
cin.getline(cChar,50);
}

void wait5Spaces(ofstream& out_stream)
{
int count = 0;
int spaceCount = 0;
out_stream.unsetf(ios_base::skipws);
while (spaceCount <=5)
{
if (count == 0)
{
out_stream << cChar[count];
}
if (spaceCount == 5)
{
out_stream << cChar[count--];
}
if (isspace(cChar[count]))
{
spaceCount++;
out_stream << " ";
}
count ++;
}
}

void display(ifstream& in_stream)
{
char cNextChar;
in_stream.unsetf(ios_base::skipws);
while ( in_stream >> cNextChar )
{
cout << cNextChar;
}

}

Oct 20, 2012 at 4:04am
Mr. Clay??

And I know you can do it through arrays, but we're not there yet. When looking up different ways through which to tackle this program, it was one of the first things that popped up :\
Oct 20, 2012 at 4:54am
Yea, but this is the only way it worked for me
Oct 20, 2012 at 12:53pm
@degausser

To me, the "word for word" instructions don't are quite match up with the examples you provide. Were they provided with the instructions, or are they your interpretation?

Taking the instruction as literally as possible,

1
2
3
4
5
6
Allow the user to enter characters 
until the following requirements have been met:
1. Read a single non-whitepsace character
2. Read 5 space characters
3. Read a single non-whitepsace character
4. Output these 7 characters to the user


It sounds like you are looking for a run of 5 spaces and will then display the chars either side of it.

But step 2 would need to read something like "read chars until you pass 5 spaces" to handle strings like "1 3444 a".

Going with the new step 2, the following code sort of handles single lines which start with a non-space, like "1 3444 a", where the 'last char' displayed is the first non-space after 5 spaces have passed by.

(This isn't what your orig. post wanted. To display "1 c" rather than "1 a" for an input of "1 3444 a", you need to keep track of the last char and then terminate the loop when you get the 6th space (but not display it), rather than terminating the loop when you get the first non-space char after the 5th space.)

For example:

Enter a string with a total of 5 embedded spaces

1   3444  a
1     a
Enter a string with a total of 5 embedded spaces

1 2 3 4 5 6 7 8 9
1     6
Enter a string with a total of 5 embedded spaces

1 21 321 4321 54321 654321
1     6

Or even

Enter a string with a total of 5 embedded spaces

Enter a string with a total of 5 embedded spaces
E     t

but has trouble with multi-line strings as the o/p occurs at the same time as the i/p procressing

Enter a string with a total of 5 embedded spaces

bcsa a
b
   d
    c
 c

To fix this you'd need to defer the o/p until the the whole of the i/p is processed.

This code also get confused by leading spaces.

But it does handle too many spaces.

Enter a string with a total of 5 embedded spaces (here there are 3 spaces between each 3)

3   3   3
3     Error!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
using namespace std;

enum {
    want_more     = -1,
    found_match   =  0,
    error_occured =  1
};

int main() {
    int ret = want_more;

    cout << "Enter a string with a total of 5 embedded spaces " << endl;
    cout << endl;

    size_t space_count = 0;

    char in = '\0';
    cin.get(in);
    cout << in;

    while(ret == want_more){
        if(' ' == in) {
            if(5 > space_count) {
                cout << in;
                ++space_count;
            } else {
                ret = error_occured;
            }
        } else {
            if(5 == space_count) {
                ret = found_match;
                cout << in;
            }
        }

        cin.get(in);
    }

    if(ret != found_match) {
        cout << "Error!" << endl;
    }
    cout << endl;

    return ret;
}

Last edited on Oct 20, 2012 at 2:03pm
Oct 20, 2012 at 4:04pm
The two examples I gave were in the book, word for word.

In your code, however, what is that enum function?
Oct 20, 2012 at 4:59pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <cctype>

int main()
{
    std::cout << "Enter a character followed by 5 spaces followed by a character:\n" ;

    // 1. Read a single non-whitespace character
    char ch ;
    while ( std::cin.get(ch) && std::isspace(ch) )
        ;

    char first = ch ;

    //2. Read 5 space characters
    unsigned spaces = 0 ;
    while ( spaces != 5 && std::cin.get(ch) )
        if ( ch == ' ' ) // if it isn't ' ', don't count it.
            ++spaces ; 

    //3. Read a single non-whitepsace character
    while ( std::cin.get(ch) && std::isspace(ch) )
        ;

    char last = ch ;

    std::cout << "You entered:\n" ;
    //4. Output these 7 characters to the user
    std::cout << first << "     " << last << '\n' ;
}


[ Edit: removed redundant std::isspace(ch) call. ]
Last edited on Oct 20, 2012 at 5:14pm
Oct 20, 2012 at 5:11pm
The two examples I gave were in the book, word for word.

In that case, the exercise it not very clear. Without the exaples, I would have coded it quite differently.

In your code, however, what is that enum function?

An enum isn't a function. It's an enumeration. See "Enumerations (enum)" section on this page:

Other Data Types
http://www.cplusplus.com/doc/tutorial/other_data_types/

Here I'm just using it as a tidier equivalent of

1
2
3
4
// C
#define want_more    -1
#define found_match   0
#define error_occured 1 


or

1
2
3
4
// consts
static const int want_more     = -1;
static const int found_match   =  0;
static const int error_occured =  1;


In this case, I don't think the compiler output would be any different it I'd used one of these alternatives.

Andy
Last edited on Oct 20, 2012 at 5:32pm
Oct 20, 2012 at 5:12pm
^^ pretty much the way I did it.

Though not being able to make the 5 spaces a string (line 29) makes the while loop @17 a little different.

~I used an array and filled it with blanks, but I guess that isn't allowed either :/~
Oct 20, 2012 at 5:27pm
I think that the only way to deal with this cases like

1
2
3
4
bcsa a

   d
 c


is to use an array (or equiv storage mechanism) to defer output until input has finished (given you're not supposed to inject your own blanks into the final output, if I understand the exercise by now).

And I did assume that more than 5 spaces was an error (that you're not allowed to just ignore extra spaces)

Andy
Last edited on Oct 20, 2012 at 5:31pm
Oct 20, 2012 at 7:04pm
I'm not seeing the problem with regards to arrays and not being able to inject your own blanks into the output (although the latter would certainly be a silly requirement.) I can see where one might interpret that more than 5 spaces was an error, but it wouldn't seem to be in the spirit of the exercise since we're discarding non-spaces while we look for our spaces. It makes sense to me to then discard whitespace while we're looking for our non-whitespace.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <cctype>

char read_non_whitespace()
{
    char ch ;
    while ( std::cin.get(ch) && std::isspace(ch) )
        ;
    return ch ;
}

char read_space()
{
    char ch ;
    while ( std::cin.get(ch) && ch != ' ' )
        ;
    return ch ;
}

int main()
{
    std::cout << "Enter a character followed by 5 spaces followed by a character:\n" ;

    // 1. Read a single non-whitespace characte
    char first = read_non_whitespace() ;

    //2. Read 5 space characters
    char s1 = read_space() ;
    char s2 = read_space() ;
    char s3 = read_space() ;
    char s4 = read_space() ;
    char s5 = read_space() ;

    //3. Read a single non-whitepsace character
    char last = read_non_whitespace() ;

    std::cout << "You entered:\n" ;
    //4. Output these 7 characters to the user
    std::cout << first << s1 << s2 << s3 << s4 << s5 << last << '\n' ;
}


Pages: 123