If you just need to spit out the uppercase version of the first letter of each string entered by the user, then you don't need an array to store any input; you just read the next character from the input stream, and then decide whether or not to display it.
Use printf
to write a prompt to the standard output stream (i.e., the console):
printf( "Gimme some words: " );
Then you'd use getchar
to read the next input character until we see a newline or EOF has been signaled, meaning you need some kind of a loop. For this example, a for
loop is somewhat natural:
for ( int c = getchar(); c != '\n' && c != EOF; c = getchar() )
{
// process input
}
The structure of a for
loop is:
for ( expr1opt ; expr2opt ; expr3opt ) statement
expr1
is evaluated once before the loop executes. It's typically used to set the initial loop state. In this case, we create the c
variable and assign it the first character read from the input stream.
expr2
is evaluated before each iteration of the loop body. The loop body will be executed if this expression evaluates to a non-zero (true
-ish) value; otherwise, the loop exits. In this case, we loop as long as EOF has not been signaled on the input stream. If expr2
is omitted completely, it's assumed to be true
.
expr3
is evaluated after each iteration of the loop body. It's typically used to update the conditions tested in expr2
. In this case, we're updating c
to be the next character read from the input stream.
Note that each of these expressions is optional; you can leave amy one or all of them blank if you want. In fact, it's pretty common to see "infinite" loops in daemons and event-driven GUI interfaces:
for ( ;; )
{
// loop "forever"
}
Now, you need to decide whether or not to print out the current character. If you want to print the first character of each string entered by the user, then you need to decide what "first character in a string" means. For this example, we'll simply assume that strings are sequences of non-whitespace characters separated by whitespace (blanks, tabs, etc.). So basically, you want to print the first non-whitespace character following one or more whitespace characters. This means you need to keep track of whether the last character was whitespace or not. The easiest way to do it is to declare a second variable to hold the previously-read character:
for ( int c = getchar(), last = ' '; c != '\n' && c != EOF; last = c, c = getchar() )
{
// process input
}
In this case, we extend expr1
to declare and initialize a second variable, last
. We initialize last
to a blank space the first time through so that we have something valid to test against.
We also extend expr3
to update last
with the current value of c
before reading the next character.
So now, we just need to decide whether to print out the current character. Our rule is going to be, "if the previous character was whitespace and the current character is not whitespace, then print the current character".
There's a standard library function, isspace
, that returns true
if the argument is a whitespace character:
#include <ctype.h> // for isspace function declaration
...
int c = getchar();
if ( isspace( c ) )
{
// c is a whitespace character
}
So we can implement our loop as follows:
for ( int c = getchar(), last = ' '; c != EOF; last = c, c = getchar() )
{
if ( isspace( last ) && !isspace( c ) )
printf( "%c", toupper( c ) );
}
Here's a complete example:
#include <stdio.h>
#include <ctype.h>
int main( void )
{
printf( "Gimme a bunch of words: " );
for ( int c = getchar(), last = ' '; c != '\n' && c != EOF; last = c, c = getchar() )
{
if ( isspace( last ) && !isspace( c ) )
putchar( toupper( c ) );
}
putchar( '\n' );
return 0;
}
And a sample run:
$ ./first
Gimme a bunch of words: this is a test of the emergency broadcast system
TIATOTEBS
This version doesn't use argc
and argv
at all, and in fact omits them from the definition of main
. You can combine the two approaches; use command line arguments if they are there; if not, prompt the user for input:
int main( int argc, char **argv )
{
if ( argc > 1 )
{
for ( int i = 1; i < argc; i++ )
putchar( toupper( argv[i][0] ) );
putchar( '\n' );
}
else
{
printf( "Gimme some words: " );
for ( int c = getchar(), last = ' '; c != '\n' && c != EOF; last = c, c = getchar() )
{
if ( isspace( last ) && !isspace( c ) )
putchar( toupper( c ) );
}
putchar( '\n' );
}
return 0;
}
So we can do either
$ ./first this is a test of the emergency broadcast system
TIATOTEBS
or
$ ./first
Gimme a bunch of words: This is a test of the emergency broadcast system
TIATOTEBS