The line
while (scanf("%[^\n]s", phrase) != EOF)
is wrong, for several reasons:
You seem to be undecided on whether to use the %s
or the %[]
conversion format specifier. The character s
is not part of the %[]
format specifier. Therefore, when using your format string, scanf
will attempt to match a literal s
. This is probably not what you want, so it should be removed from the format string.
If scanf
is unable to match any characters because the line is empty, it will return 0
and will not touch the contents of phrase
. However, you are incorrectly treating the return value of 0
as success.
If the user enters more than 255 characters, then you will be writing to the array phrase
out of bounds, causing undefined behavior (i.e your program may crash). Therefore, you should limit the number of matched characters to 255 characters, so that the function won't write more than 256 characters (including the terminating null character of the string).
For the reasons stated above, you should change the line to the following:
while ( scanf( "%255[^\n]", phrase ) != 1 )
Also, this scanf
statement will not consume the newline character from the input stream, so the next function call to scanf
will fail. Therefore, you must call a function to consume the newline character from the input stream, for example by calling getchar
, or by telling scanf to consume all whitespace input beforehand, like this:
while ( scanf( " %255[^\n]", phrase ) != 1 )
Alternatively, you could use the function fgets
instead (which I recommend), as that function will also consume the newline character and write it to the string.
while ( fgets( phrase, sizeof phrase, stdin ) != NULL )
When using the function fgets
, you should also verify that an entire line was read in, for example by writing the following code afterwards:
//verify that entire line was read in
if ( strchr( phrase, '\n' ) == NULL )
{
printf( "line to long for input buffer!\n" );
exit( EXIT_FAILURE );
}
Note that if you decide to use the function fgets
, you will have an additional newline character at the end of the line, instead of only a '\0'
, so in the function alterChar
, you will have to change the line
for (i = 0; phrase[i] != '\0'; i++)
to
for (i = 0; phrase[i] != '\n'; i++)
Another problem in your code is that the line
alterChar(i, phrase);
does not make sense. You are passing the value of an uninitialized variable to the function.
You should probably change the function prototype from
void alterChar(int i, char phrase[])
to
void alterChar( char phrase[] )
and maybe also give the function a better name, as it does not deal with single characters, but whole strings, and also prints it:
void alterAndPrintPhrase( char phrase[] )
Also, in that function, you should move the line
printf("%s\n", phrase);
outside the loop.
After applying all the fixes mentioned above, your code should look like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void alterAndPrintPhrase( char phrase[] )
{
for ( int i = 0; phrase[i] != '\n'; i++ )
{
if (phrase[i] == '@')
{
phrase[i] = 'a';
}
if (phrase[i] == '&')
{
phrase[i] = 'e';
}
if (phrase[i] == '!')
{
phrase[i] = 'i';
}
if (phrase[i] == '*')
{
phrase[i] = 'o';
}
if (phrase[i] == '#')
{
phrase[i] = 'u';
}
}
printf( "%s\n", phrase );
}
int main()
{
char phrase[256];
while ( fgets( phrase, sizeof phrase, stdin ) != NULL )
{
//verify that entire line was read in
if ( strchr( phrase, '\n' ) == NULL )
{
printf( "line to long for input buffer!\n" );
exit( EXIT_FAILURE );
}
alterAndPrintPhrase( phrase );
}
return 0;
}
This program has the following behavior:
Input:
Th!s !s @ t&st.
Output:
This is a test.