I'm reading characters into an array and try to print them out. The code is given below.
#include <stdio.h>
#include <ctype.h>
#define N 50
int read_message(char a[], int n)
{
char ch;
int i = 0;
printf("Enter a message: ");
for (i = 0; (ch = getchar()) != EOF && ch != '\n'; i ) {
if (toupper(ch) >= 'A' && toupper(ch) <= 'Z') {
a[i] = tolower(ch);
}
}
return i;
}
void print_message(char a[], int n)
{
int i;
for (i = 0; i < n; i )
printf("%c", a[i]);
printf("\n");
}
int main()
{
char message[N];
int message_len = read_message(message, N);
print_message(message, message_len);
}
When I enter "He h", it shows "he蘦".
However, if I change the read_message()
in the following way, the problem is solved.
int read_message(char a[], int n)
{
char ch;
int i = 0;
printf("Enter a message: ");
while ((ch = getchar()) != EOF && ch != '\n') {
if (toupper(ch) >= 'A' && toupper(ch) <= 'Z') {
a[i] = tolower(ch);
i ;
}
}
return i;
}
I heard that for
and while
are equivalent, so I have no idea why this is happening.
CodePudding user response:
In the first version of read_message()
you have the following issues:
int ch
asgetchar()
returns anint
(on my system char is unsigned and EOF defined as -1).- Only increment
i
when you have a valid letter which is in theif
body not for each iteration of the loop. \0
-terminate the stringa
.a
is subject to overflows (i >= n
).- (minor) prefer using unsigned types for length (
unsigned
,size_t
etc). - (minor and not fixed to minimize change) replace
for
withwhile
as it now has neither initialization or increment parts.
unsigned read_message(char a[], unsigned n) {
printf("Enter a message: ");
int ch;
unsigned i = 0;
for (; (ch = getchar()) != EOF && ch != '\n' && (i 1) < n;) {
if (isalpha(ch)) {
a[i ] = tolower(ch);
}
}
if(n)
a[i] = '\0';
return i;
}
If you swap the order of arguments you can document the relationship between n
and a
:
unsigned read_message(unsigned n, char a[n])