将小写字母转换为大写字母,反之亦然 C 程序

问题描述 投票:0回答:5

我正在努力实现一个将小写字母转换为大写字母的函数,反之亦然。

我不明白的是,当我在 main 中使用代码时,它可以工作,当我尝试将它放入一个函数时,它不起作用。我不明白。

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

char sentence[100];
int count, ch, i;

void KUlowerL(char *sentence)
{
    printf("%s", sentence); // Test if I get char from sentence. it works ?!?!
    for (i=0;(sentence[i] = getchar()) != '\n'; i++); /* enters the user sentence to change the case */

    sentence[i] = '\0';
    count = i;
    printf("Der Satz ist: %s", sentence);
    printf("\nDer veränderte Satz ist: ");

    for (i = 0; i < count; i++)
    {
        ch = islower(sentence[i]) ? toupper(sentence[i]) : tolower(sentence[i]);
        putchar(ch);
    }
}

int main()
{
    printf("Bitte gebe deinen Satz ein: ");
    fgets(sentence, 100, stdin);
    KUlowerL(sentence);
}
c c-strings function-definition function-call
5个回答
0
投票

我注意到以下几点:

fgets(sentence, 100, stdin);

...然后我注意到您正在传递给

KUlowerL
,那么
getchar
循环是怎么回事?您已经使用
fgets
代码完成了这项工作,是吗?

注意

getchar
tolower
,这两者以
fgets
无法关联的方式结合在一起......您需要将
char
值转换为
unsigned char
并传递给
tolower
,他们将被提升为
int
,而
getchar
返回已经为您铸造的角色,因此只要您将该返回值保留为
int
形式,就无需进行铸造...


0
投票

对于初学者来说,使用这样的全局变量是一个坏主意

char sentence[100];
int count, ch, i;

并且无需将它们定义为全局。

该函数已经通过其参数获取了一个字符串。因此使用

getchar
的调用重写它是没有意义的。

void KUlowerL(char *sentence)
{
    printf("%s", sentence); // Test if I get char from sentence. it works ?!?!
    for (i=0;(sentence[i] = getchar()) != '\n'; i++); /* enters the user sentence to change the case */ 
    //...

该函数也不会更改已处理的字符串。

函数可以通过以下方式声明和定义

char * KUlowerL( char *sentence )
{
    for ( char *p = sentence; *p != '\0'; ++p )
    {
        if ( islower( ( unsigned char )*p ) )
        {
            *p = toupper( ( unsigned char )*p );
        }
        else
        {
            *p = tolower( ( unsigned char )*p );
        }
    }

    return sentence;
}

在 main 函数中可以这样调用

int main( void )
{
    enum { N = 100 };
    char sentence[N];

    printf( "Bitte gebe deinen Satz ein: " );
    fgets( sentence, N, stdin );

    printf( "%s", KUlowerL(sentence) );
}

0
投票

您不需要这个

?
运算符。该函数将更改字母的大小写,忽略非字母。

ch = toupper((unsigned char)sentence[i]);

下面这行没有任何意义

for (i=0;(sentence[i] = getchar()) != '\n'; i++); 

您只需迭代字符串

void KUlowerL(char *sentence)
{
    while(*sentence && *sentence != '\n')
        putchar(toupper((unsigned char)*sentence++));
}

int main()
{
    char sentence[100];
    printf("Bitte gebe deinen Satz ein: ");
    fgets(sentence, 100, stdin);
    printf("\n");
    KUlowerL(sentence);
}

编辑:

更换外壳

void SwapCase(char *sentence)
{
    while(*sentence && *sentence != '\n')
    {
        int c = *sentence;

        if(islower((unsigned char)c)) c = toupper((unsigned char)c);
        else if(isupper((unsigned char)c)) c = tolower((unsigned char)c);
        sentence++;
        putchar(c);
    }
}

int main()
{
    char sentence[100];
    printf("Bitte gebe deinen Satz ein: ");
    fgets(sentence, 100, stdin);
    printf("\n");
    SwapCase(sentence);
}

https://godbolt.org/z/WdcKh5TfK


0
投票

它似乎不起作用的原因是使用

getchar()
循环,并且您不希望输入句子 ZWEI MAL!!!您按 RETURN 键但什么也看不到,因为第二个“句子”的长度为零......

检查了你的代码并做了一些更改...

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

char sentence[100]; // global. need not be passed around
// other variables declared/defined closer to where they are used.

// main() prints the first input sentence so no need to pass a global variable
void KUlowerL( void )
{
    printf("Bitte gebe deinen Satz noch mal ein: ");
    // that for() loop was alright, but doing the work of a standard library function.
    // Use (proven) library functions when possible.
    // "sizeof" is better than repeating "magic number" of 100
    // The compiler knows the size and sizeof means you can grow or
    // shrink buffer in one place, not two...
    fgets( sentence, sizeof sentence, stdin );

    // measure the length (incl. the '\n'
    int count = strlen( sentence );
    printf("Der Satz hält %d buchstabben: %s", count, sentence );

    printf("\nDer veränderte Satz ist: ");
    for( int i = 0; i < count; i++ )
    {
        // 'c' is easier to read than 3 copies of 'sentence[i]'
        char c = sentence[ i ];
        // You want to 'swap' the upper/lower case-ness of each letter
        putchar( islower( c ) ? toupper( c ) : tolower( c ) );
    }
}


int main()
{
    printf("Bitte gebe deinen Satz ein: ");
    fgets(sentence, 100, stdin);

    printf("main(): sentence is %s", sentence ); // includes '\n' from fgets()

    KUlowerL();

    return 0;
}

输出:

Bitte gebe deinen Satz ein: Guten morgen
main(): sentence is Guten morgen
Bitte gebe deinen Satz noch mal ein: Schlaff Schoen
Der Satz hõlt 15 buchstabben: Schlaff Schoen
{empty line because buffer contains '\n' too.)
Der verõnderte Satz ist: sCHLAFF sCHOEN

0
投票

实现一个将小写字母转换为大写字母的函数,反之亦然。

完善案例交换功能

  • 字符串空字符结尾。输入的line

    '\n'
    结尾。更好地创建使用 string 并停止在 null 字符 的函数,而不是
    '\n'

  • 迭代字符串一次。不需要先求出字符串长度再进行第二次转换。一起做。

  • KUlowerL()
    中删除用户 I/O 代码。让调用代码读取数据并打印文本。 OP 尝试读取 2 行输入(一次在
    main()
    中,一次在
    KUlowerL()
    中)会导致麻烦。它可以解释“当我在 main 中使用代码时,它可以工作,而当我尝试将其放入函数中时,它不起作用。”

  • is...(int ch)
    to...(int ch)
    对于值
    [0...UCHAR_MAX]
    EOF
    定义良好,否则如果
    ch < 0
    ,结果是 未定义行为 (UB)。

  • str...()
    函数的执行就像通过 unsigned char * 完成对
    strings
    的访问一样,即使
    char
    signed。这个大小写转换代码应该同样执行。

  • KUlowerL()
    对于交换大小写的函数来说是一个令人困惑的名称。

  • 返回有用的内容,例如字符串的开头。


#include <ctype.h>

char *TLG_swapcase(char *s) {
  unsigned char *us = (unsigned char *) s;
  while (*us) {  // Test for string's end.
    *us = islower(*us) ? toupper(*us) : tolower(*us);  // Swap  case.
    us++; // Advance pointer to next character.
  }
  return s;
}

测试代码

  • 使用本地缓冲区。

  • 最好测试输入函数的返回值来判断输入是否成功。

#include <stdio.h>

int main(void) {
  char line[100];
  printf("Bitte gebe deinen Satz ein: ");
  if (fgets(line, sizeof line, stdin)) {
    printf("%s", TLG_swapcase(line));
  }
  return 0;  // Optional with main().
}
© www.soinside.com 2019 - 2024. All rights reserved.