2015-06-17 71 views
0

我在做练习题对即将到来的考试,但不能似乎要弄清楚一个问题,其中目标是:连接两个单独字符串的大写字母在C

编写一个C语言程序读取两个字符串s1s2。每个字符串的最大大小为25.形成两个新字符串,称为upperlower。 Lower由小写字母s1s2连接而成,而upper包含两个字符串的大写字母的连接。

例如: 输入:

S1:GREENblue
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); 
} 
+0

'scanf(“%s”,&s1);' - >'scanf(“%24s”,s1);',对于's2'也一样 –

+0

downvote的任何特定原因?在问题和第一个答案上?! – Pandrei

回答

-1

一个节目,我觉得你得到了普遍的想法,但错过了一些细节很重要:

  • 不使用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); 
    

这应该做的工作。

+0

是的:)这个工作,我明白这一点非常感谢你们所有人的帮助我会记住你所有的指针......再次感谢 – TriniProgrammer

+0

祝你考试顺利! :) – Pandrei

+0

@Pandrei Minor:'for(i = 0; i chux

1

在你的代码,在strcat()

strcat (s1, s2); 

s1使用可能是没有足够的内存来存放连接字符串。在这种情况下,它会调用undefined behaviour

从man页面,

如果dest不够大,程序的行为是不可预知的;缓冲区溢出是攻击安全程序的最佳途径。

根据您的要求

The maximum size of each string is 25

需要长度为25 X 2的一个目的地缓冲液(用于char S)+ 1(对于空)。

此外,它表示,您需要s1s226元素,每个元素,以适应null。

根据您的要求,也有需要你的程序一定的设计变化,

  1. 你需要s1s226元素,每个元素,用于容纳空。

  2. upperlower都必须具有总输入大小的大小。如果s1s2都是完全大写(或小写),请考虑场景。所以,你需要upper[51]lower[51]

+0

@RhysHinkson关于缓冲区大小?我会添加一行。 –

0

这是我到目前为止有::)

#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(S )而不是动态分配的数组。

下面是一个使用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; 
} 
0

您还有一个问题:如果输入的字符串长于23个字符,会发生什么情况?你的程序会崩溃。

如果最大大小为25个字符,则您的数组的大小必须是26而不是25,以说明终止空值。

为了安全起见,您必须设置s1 [N-1] ='\ 0'和s2 [N-1] ='\ n'。 如果为第一个字符串输入的内容太长,则第二个字符串将最终为残留字符,忽略在第二个字符串提示后输入的任何内容。

+0

细节:'scanf(“%s”,&s1);'(应该是'scanf(“%s”,s1);''或更好''scanf(“%24s”,s1);')不会在's1'中保存''\ n''.如果用户输入超过24个非空白字符,而不是23个。 – chux

相关问题