问题
I'm very new to C and I'm trying to write a program that checks if a string contains any uppercase letters, and if it does, prints them out. I'm using https://www.onlinegdb.com/online_c_compiler# as my compiler (cause I don't have access to my personal computer right now) and after a test run, the results are (p.s. I know gets isn't safe):
main.c:16:5: warning: ‘gets’ is deprecated [-Wdeprecated-declarations]
/usr/include/stdio.h:638:14: note: declared here
main.c:(.text+0x26): warning: the `gets' function is dangerous and should not be used.
sTrInG
Contains Uppercase!
Uppercase Letters:0
...Program finished with exit code 0
Press ENTER to exit console.
In this case, I expect an output something like this:
Contains Uppercase!
Uppercase Letters: TIG
My script:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main()
{
char str[100];
gets(str);
int containsUpper = 0;
char upperLetters[100] = {0};
for (int i=0; i < strlen(str); i++) {
if (islower(str[i])) {
continue;
} else {
containsUpper = 1;
upperLetters[i] = str[i]; // is this the bad line?
}
}
if (containsUpper) {
printf("Contains Uppercase!\n");
printf("Uppercase Letters:");
printf("%zu\n", strlen(upperLetters)); // prints 0 so upperLetters is empty..?
for (int i=0; i < strlen(upperLetters); i++) {
printf("%c", upperLetters[i]);
}
} else {
printf("Does not contain Uppercase!");
}
return 0;
}
回答1:
You want the loop to be:
int i, j=0;
for (i=0; i < strlen(str); i++) {
if (isupper((unsigned char)str[i])) {
upperLetters[j++] = str[i];
}
}
upperLetters[j]= '\0';
containsUpper = (j>0);
That is, keep a separate index of the upper letters array. And don't forget to terminate it.
A better way for the loop is:
int i, j, k;
for (i=0, j=0, k=strlen(str); i < k; i++) {
as this calls strlen
only once.
EDIT: As user LxerLx pointed out, a character which is not a lower case letter does not have to be an upper case letter. I updated the loop for this.
回答2:
This loop
for (int i=0; i < strlen(str); i++) {
if (islower(str[i])) {
continue;
} else {
containsUpper = 1;
upperLetters[i] = str[i]; // is this the bad line?
}
}
1) is incorrect and 2) suffers from a bad style of programming.
You should append upper case letters to the character array upperLetters
consistently that you are not doing. Also if a character is not a lower case character it does not mean that the character is an upper case character. For example in general it can be a digit or a punctuation.
Also there is no need to call the function strlen
. An argument of the function call should be cast to unsigned char. Otherwise it can occur that a call of the function will invoke undefined behavior.
The part of the loop with the continue statement is redundant.
The loop can look for example the following way
for ( size_t i = 0, j = 0; str[i] != '\0'; i++ )
{
if ( isupper( ( unsigned char )str[i] ) )
{
upperLetters[j++] = str[i];
}
}
containsUpper = upperLetters[0] != '\0';
If you need the number of uppercase letters in other part pf the program then the loop can look like
size_t n = 0;
for ( size_t i = 0; str[i] != '\0'; i++ )
{
if ( isupper( ( unsigned char )str[i] ) )
{
upperLetters[n++] = str[i];
}
}
if ( n )
{
printf( "Contains Uppercase!\n" );
printf( "Uppercase Letters: " );
printf("%zu\n", n );
for ( size_t i = 0; i < n; i++ )
{
printf( "%c", upperLetters[i] );
}
//…
Or instead of the loop
for ( size_t i = 0; i < n; i++ )
{
printf( "%c", upperLetters[i] );
}
you could just write
printf( "%s\n", upperLetters );
because the array was zero-initialized and as such it contains a string.
As the compiler reported the function gets is unsafe and is not supported by the C Standard. Instead use the function fgets
.
For example
fgets( str, sizeof( str ), stdin );
回答3:
I wouldn't consider numbers or characters like !?#%&
to be uppercase letters, yet your program counts them as such. You absolutely must not use gets
, but there is no reason in this case to replace it with fgets
since your program is not fundamentally line-oriented. You simply don't care about lines. Just do:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int
main(void)
{
int c;
char upperLetters[100] = {0};
unsigned k = 0;
while( ( c = getchar()) != EOF && k < sizeof upperLetters ) {
if( isupper(c)) {
upperLetters[k++] = c;
}
}
if (k) {
puts("Contains Uppercase!");
printf("Uppercase Letters: %u\n%s\n", k, upperLetters);
} else {
fprintf(stderr, "Does not contain Uppercase!");
}
return k != 0;
}
(Note that the original program only looks at the first line of input. Whether that is a bug or intentional is not clear. If it is intentional, add a check and break out of the loop when after the first newline character is read.)
来源:https://stackoverflow.com/questions/59648189/how-to-append-characters-to-a-string-array-in-c