Character I/O, and inputting spaces.

Pages: 123
I just want a blank space.
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
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
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.
Well, given the new examples, the termination condition cannot be '\n'.

The second example isn't impossible, inherently or otherwise.
All I want to know is how to extract the first and last character of anything I input :|
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
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?
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
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.
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;
}

}

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 :\
Yea, but this is the only way it worked for me
@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
The two examples I gave were in the book, word for word.

In your code, however, what is that enum function?
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
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
^^ 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 :/~
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
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