我正在努力实现一个将小写字母转换为大写字母的函数,反之亦然。
我不明白的是,当我在 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);
}
我注意到以下几点:
fgets(sentence, 100, stdin);
...然后我注意到您正在传递给
KUlowerL
,那么 getchar
循环是怎么回事?您已经使用 fgets
代码完成了这项工作,是吗?
注意
getchar
和 tolower
,这两者以 fgets
无法关联的方式结合在一起......您需要将 char
值转换为 unsigned char
并传递给 tolower
,他们将被提升为 int
,而 getchar
返回已经为您铸造的角色,因此只要您将该返回值保留为 int
形式,就无需进行铸造...
对于初学者来说,使用这样的全局变量是一个坏主意
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) );
}
您不需要这个
?
运算符。该函数将更改字母的大小写,忽略非字母。
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);
}
它似乎不起作用的原因是使用
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
实现一个将小写字母转换为大写字母的函数,反之亦然。
完善案例交换功能
字符串以空字符结尾。输入的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().
}