How to append characters to a string array in C

走远了吗. 提交于 2020-01-25 06:48:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!