将字符数组中的大写字母分离到新数组中并在 C 中为其重新分配内存

Separating capital letters from char array into the new array and rellocating memory for it in C

我有一个数组,我在其中输入元素数量,输入所有元素,打印它们,然后我应该将所有大写字母转移到新数组中,将小写字母转移到另一个数组中,为它们分配内存并打印出来。我试过这种方法,但没有用:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int n, i, j, counter=0, counter1=0;
    char *arrA, *arrB, *arrC;

    printf("Enter number of elements: ");
    scanf("%d", &n);
    printf("Enter elements of array: \n");


    arrA = (char*)malloc(n * sizeof(char));

    for (i = 0; i < n; i++) {
        scanf(" %c", &arrA[i]);
    }

    for (i = 0; i < n; i++) {
        printf("%d. element of array is: %c\n", i + 1, arrA[i]);
    }
    arrB = (char*)malloc(counter * sizeof(char));
    arrC = (char*)malloc(counter1 * sizeof(char));

    for (i = 0; i < n; i++) {
        if ((arrA[i] >= 'A') && (arrA[i] <= 'Z')) {
            counter++;
            *arrB = *arrA;
        }
    }
    for (i = 0; i < n; i++) {
        if ((arrA[i] >= 'a') && (arrA[i] <= 'z')) {
            counter1++;
            *arrC = *arrA;
        }
    }


    for (i = 0; i < counter; i++) {
        printf("%d. element of array B is: %c\n", i + 1, arrB[i]);
    }
    for (i = 0; i < counter1; i++) {
        printf("%d. element of array C is: %c\n", i + 1, arrC[i]);
    }
    free(arrA);
    free(arrB);
    free(arrC);

    return 0;
}

如何将这些大写字母分隔到新数组中 "arrB"?

您已经为arrB和arrC分配了字符值,在给它们分配内存之前,您需要先分配内存,然后复制其中的字符

同时检查作业

 *arrB = *arrA;

改为

 arrB[j++] = arrA[i];// maintain seperator counter j for arrB as you want to increment it only for capital letters, init it to 0 prior to starting loop

你需要为 arrC 的循环做同样的事情

您可以采用两种不同的方法。

第一种方法是为 arrBarrC 分配最大数量的字符(即 arrB = malloc(n * sizeof(char)))。一旦你复制了字符并最终知道它们的编号(即 arrB = realloc(arrB, countCapital * sizeof(char))),你就可以使用一些未使用的内存或 realloc 这些数组:

#include <stdio.h>
#include <stdlib.h>

int isCapitalLetter(char c) {
    return (c >= 'A') && (c <= 'Z');
}

int isSmallLetter(char c) {
    return (c >= 'a') && (c <= 'z');
}

int main() {
    int n=0, i, countCapital, countSmall;
    char *arrA, *arrB, *arrC;


    printf("Enter number of elements: ");
    scanf("%d", &n);
    printf("Enter elements of array: \n");


    arrA = malloc(n * sizeof(char));
    arrB = malloc(n * sizeof(char));
    arrC = malloc(n * sizeof(char));

    for (i = 0; i < n; i++) {
        scanf(" %c", &arrA[i]);
    }

    for (i = 0; i < n; i++) {
        printf("%d. element of array is: %c\n", i + 1, arrA[i]);
    }

    countCapital = 0;
    countSmall = 0;
    for (i = 0; i < n; i++) {
        char c = arrA[i];
        if (isCapitalLetter(c)) {
            arrB[countCapital++] = c;
        }
        else if (isSmallLetter(c)) {
            arrC[countSmall++] = c;
        }
    }
    arrB = realloc(arrB, countCapital * sizeof(char));
    arrC = realloc(arrC, countSmall * sizeof(char));

    for (i = 0; i < countCapital; i++) {
        printf("%d. element of array B is: %c\n", i + 1, arrB[i]);
    }
    for (i = 0; i < countSmall; i++) {
        printf("%d. element of array C is: %c\n", i + 1, arrC[i]);
    }
    free(arrA);
    free(arrB);
    free(arrC);

    return 0;
}

第二种方法是分别计算大写字母和小写字母;然后在将值复制到它们之前相应地分配 arrBarrC

#include <stdio.h>
#include <stdlib.h>

int isCapitalLetter(char c) {
    return (c >= 'A') && (c <= 'Z');
}

int isSmallLetter(char c) {
    return (c >= 'a') && (c <= 'z');
}

int main() {
    int n=0, i, countCapital, countSmall;
    char *arrA, *arrB, *arrC;


    printf("Enter number of elements: ");
    scanf("%d", &n);
    printf("Enter elements of array: \n");


    arrA = malloc(n * sizeof(char));

    for (i = 0; i < n; i++) {
        scanf(" %c", &arrA[i]);
    }

    for (i = 0; i < n; i++) {
        printf("%d. element of array is: %c\n", i + 1, arrA[i]);
    }

    countCapital = 0;
    countSmall = 0;
    for (i = 0; i < n; i++) {
        if (isCapitalLetter(arrA[i])) {
            countCapital++;
        }
        else if (isSmallLetter(arrA[i])) {
            countSmall++;
        }
    }

    arrB = malloc(countCapital * sizeof(char));
    arrC = malloc(countSmall * sizeof(char));

    char *writeCaptialPtr = arrB;
    char *writeSmallPtr = arrC;
    for (i = 0; i < n; i++) {
        char c = arrA[i];
        if (isCapitalLetter(c)) {
            *writeCaptialPtr++ = c;
        }
        else if (isSmallLetter(c)) {
            *writeSmallPtr++ = c;
        }
    }

    for (i = 0; i < countCapital; i++) {
        printf("%d. element of array B is: %c\n", i + 1, arrB[i]);
    }
    for (i = 0; i < countSmall; i++) {
        printf("%d. element of array C is: %c\n", i + 1, arrC[i]);
    }
    free(arrA);
    free(arrB);
    free(arrC);

    return 0;
}

事实上你做的一切都是正确的,除了首先你必须计算大写字母的数量和小写字母的数量,然后才为数组分配内存并复制其中的相应字母。

否则这些语句

arrB = (char*)malloc(counter * sizeof(char));
arrC = (char*)malloc(counter1 * sizeof(char));

没有意义,因为此时程序的变量 countercounter1 等于零。

以及相应的这些陈述

*arrB = *arrA;
*arrC = *arrA;

也没有意义,因为它们引用了相同的数组元素。

您还应该使用标准 C 函数 isupperislower

程序如下所示

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

int main( void ) 
{
    size_t n;
    size_t i, j, k;
    size_t counter, counter1;
    char *arrA, *arrB, *arrC;

    printf( "Enter number of elements: " );
    scanf( "%zu", &n );

    printf( "Enter elements of array separated by spaces: \n" );


    arrA = ( char* )malloc( n * sizeof( char ) );

    for ( i = 0; i < n; i++ ) scanf( " %c", &arrA[i] );

    putchar( '\n' );

    for ( i = 0; i < n; i++ ) 
    {
        printf( "%zu. element of array is: %c\n", i + 1, arrA[i]);
    }

    counter = counter1 = 0;

    for ( i = 0; i < n; i++ ) 
    {
        if ( isupper( ( unsigned char )arrA[i] ) ) 
        {
            counter++;
        }
        else if ( islower( ( unsigned char )arrA[i] ) )
        {
            counter1++;
        }
    }

    arrB = arrC = NULL;
    if ( counter )  arrB = ( char* )malloc( counter  * sizeof( char ) );
    if ( counter1 ) arrC = ( char* )malloc( counter1 * sizeof( char ) );

    for ( i = j = k = 0; i < n; i++ ) 
    {
        if ( isupper( ( unsigned char )arrA[i] ) ) 
        {
            arrB[j++] = arrA[i];
        }
        else if ( islower( ( unsigned char )arrA[i] ) )
        {
            arrC[k++] = arrA[i];
        }
    }

    if ( arrB ) putchar( '\n' );

    for ( j = 0; j < counter; j++ ) 
    {
        printf( "%zu. element of array B is: %c\n", j + 1, arrB[j] );
    }

    if ( arrC ) putchar( '\n' );

    for ( k = 0; k < counter1; k++ ) 
    {
        printf( "%zu. element of array C is: %c\n", k + 1, arrC[k] );
    }

    free( arrC );
    free( arrB );
    free (arrA );

    return 0;
}

程序输出可能看起来像

Enter number of elements: 10
Enter elements of array separated by spaces: a b c 1 2 Z x Y w 5

1. element of array is: a
2. element of array is: b
3. element of array is: c
4. element of array is: 1
5. element of array is: 2
6. element of array is: Z
7. element of array is: x
8. element of array is: Y
9. element of array is: w
10. element of array is: 5

1. element of array B is: Z
2. element of array B is: Y

1. element of array C is: a
2. element of array C is: b
3. element of array C is: c
4. element of array C is: x
5. element of array C is: w

如果您不能使用 isupperislower 函数,那么您可以将它们替换为您所使用的条件。例如

if ( 'A' <= arrA[i] && arrA[i] <= 'Z' )
{
//...