簡體   English   中英

在c中連接兩個單獨字符串的大寫字母

[英]concatenating uppercase letters of two separate strings in c

我正在為即將舉行的考試准備練習題,但似乎無法找出目標是什么的問題:

編寫一個C程序來讀取兩個字符串s1s2 每個字符串的最大大小為25。形成兩個新字符串,分別稱為upperlower 下由小寫字母的s1s2級聯而upper包含兩個字符串的大寫字母的串聯。

例如:輸入:

s1:綠色藍色
s2:busCAR

輸出:

上部:GREENCAR
下層:bluebus

我已經嘗試了幾天,但無法完全弄清楚。

這是我到目前為止的內容:

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <conio.h>

int main()
{
    int i, j;
    char s1[25];
    char s2[25];
    char upper[25];
    char lower[25];

    printf ("Please enter first string: ");
    scanf ("%s", &s1);
    printf ("Please enter second string: ");
    scanf ("%s", &s2);

    strcat (s1, s2);

    for (i=0; i<strlen(s1); i++)
    {
        if (s1[i]>=65 && s1[i] <= 90)
        {
            upper[i] = s1[i];
        }
        else
        {
            lower[i] = s1[i];
        }
    }
    printf ("Upper: %s\n", upper);
    printf ("Lower: %s\n", lower);
}

在您的代碼中,使用strcat()

 strcat (s1, s2);

s1可能沒有足夠的內存來容納串聯的字符串。 在這種情況下,它將調用未定義的行為

在手冊頁中,

如果dest不夠大,則程序行為是不可預測的; 緩沖區溢出是攻擊安全程序的最常用方法。

根據您的要求

The maximum size of each string is 25

您需要一個長度為25 X 2(對於char )+1(對於null)的目標緩沖區。

此外,它還表明,您需要s1s2分別具有26元素來容納空值。

根據您的要求,您的程序需要進行某些設計更改,例如

  1. 您需要s1s2分別具有26元素以容納null。

  2. upperlower都必須具有輸入大小總和的大小。 考慮一下s1s2都完全大寫(或小寫)的情況。 因此,您需要upper[51]lower[51]

這是我到目前為止的內容::)

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

#define N   25

int main(void)
{
    char s1[N];
    char s2[N];
    char *upper, *lower;
    char *p, *q;
    size_t n1, n2;

    printf( "Please enter first string: " );
    fgets( s1, N, stdin );

    printf( "Please enter second string: " );
    fgets( s2, N, stdin );

    n1 = 0; n2 = 0;

    for ( p = s1; *p; ++p )
    {
        if ( isupper( ( unsigned char )*p ) ) ++n1;
        else if ( islower( ( unsigned char )*p ) ) ++n2;
    }

    for ( p = s2; *p; ++p )
    {
        if ( isupper( ( unsigned char )*p ) ) ++n1;
        else if ( islower( ( unsigned char )*p ) ) ++n2;
    }

    upper = NULL; lower = NULL;

    if ( n1 && ( upper = ( char * )malloc( n1 + 1 ) ) )
    {
        q = upper;

        for ( p = s1; *p; ++p )
        {
            if ( isupper( ( unsigned char )*p ) ) *q++ = *p;
        }

        for ( p = s2; *p; ++p )
        {
            if ( isupper( ( unsigned char )*p ) ) *q++ = *p;
        }

        *q = '\0';
    }       

    if ( n2 && ( lower = ( char * )malloc( n1 + 1 ) ) )
    {
        q = lower;

        for ( p = s1; *p; ++p )
        {
            if ( islower( ( unsigned char )*p ) ) *q++ = *p;
        }

        for ( p = s2; *p; ++p )
        {
            if ( islower( ( unsigned char )*p ) ) *q++ = *p;
        }

        *q = '\0';
    }       

    if ( upper ) printf( "Upper: %s\n", upper );
    if ( lower ) printf( "Lower: %s\n", lower );

    free( upper );
    free( lower );

    return 0;
}

程序輸出可能看起來像

Please enter first string: GREENblue
Please enter second string: busCAR
Upper: GREENCAR
Lower: bluebus

如果您的編譯器支持可變長度數組,則可以使用VLA代替動態分配的數組。

這是使用VLA的程序

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

#define N   25

int main(void)
{
    char s1[N];
    char s2[N];

    printf( "Please enter first string: " );
    fgets( s1, N, stdin );

    printf( "Please enter second string: " );
    fgets( s2, N, stdin );

    size_t n1 = 0, n2 = 0;

    for ( const char *p = s1; *p; ++p )
    {
        if ( isupper( ( unsigned char )*p ) ) ++n1;
        else if ( islower( ( unsigned char )*p ) ) ++n2;
    }

    for ( const char *p = s2; *p; ++p )
    {
        if ( isupper( ( unsigned char )*p ) ) ++n1;
        else if ( islower( ( unsigned char )*p ) ) ++n2;
    }


    char upper[n1 + 1];
    char lower[n2 + 1];

    if ( n1 )
    {
        char *q = upper;

        for ( const char *p = s1; *p; ++p )
        {
            if ( isupper( ( unsigned char )*p ) ) *q++ = *p;
        }

        for ( const char *p = s2; *p; ++p )
        {
            if ( isupper( ( unsigned char )*p ) ) *q++ = *p;
        }

        *q = '\0';
    }       

    if ( n2 )
    {
        char *q = lower;

        for ( const char *p = s1; *p; ++p )
        {
            if ( islower( ( unsigned char )*p ) ) *q++ = *p;
        }

        for ( const char *p = s2; *p; ++p )
        {
            if ( islower( ( unsigned char )*p ) ) *q++ = *p;
        }

        *q = '\0';
    }       

    if ( n1 ) printf( "Upper: %s\n", upper );
    if ( n2 ) printf( "Lower: %s\n", lower );


    return 0;
}

您仍然有一個問題:如果輸入的字符串長於23個字符,會發生什么? 您的程序將崩潰。

如果最大大小為25個字符,則必須將數組的尺寸設置為26,而不是25,以說明終止NULL。

然后,為了安全起見,必須設置s1 [N-1] ='\\ 0'和s2 [N-1] ='\\ n'。 如果您為第一個字符串輸入的內容過長,則第二個字符串最終將成為剩余字符,而忽略您在提示輸入第二個字符串后輸入的任何內容。

我認為您已經掌握了總體思路,但錯過了一些重要的細節:

  • 不要使用strcat連接兩個字符串。 您已經將它們每個都放在自己的緩沖區中,如果要執行此操作,最好確保有足夠的內存來容納較大的結果字符串。

  • if (s1[i]>=65 && s1[i] <= 90)此條件對於檢查大寫字母是很好的,但是它的取反使您擁有其他所有東西,包括小寫字母,數字等。因此更好為了安全起見,有3種情況(大寫,小寫以及其他所有內容)。

  • 如果要打印上/下數組的內容,請確保附加'\\0'字符,以便打印函數將它們解釋為字符串。

     j=0; //iterator for lower k=0; //iterator for upper for (i=0; i<strlen(s1); i++) { if (s1[i]>='A' && s1[i] <= 'Z') // a bit more clear { upper[k++] = s1[i]; } else { if (s1[i]>='a' && s1[i] <= 'z') { lower[j++] = s1[i]; } else { //print something or just exit... } } } for (i=0; i<strlen(s2); i++) { if (s2[i]>='A' && s2[i] <= 'Z') // a bit more clear { upper[k++] = s2[i]; } else { if (s2[i]>='a' && s2[i] <= 'z') { lower[j++] = s2[i]; } else { //print something or just exit... } } } //add the string terminator character lower[j] = '\\0'; upper[k] = '\\0'; //print the result printf ("Upper: %s\\n", upper); printf ("Lower: %s\\n", lower); 

這應該做的工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM