I'am trying really hard to impliment a function that will convert lowercase letters to uppercase letters and vice-versa.
What I don't understand is when I use the code in the main it works when I try to put it in an function it doesn't work. I don't get it.
#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);
}
CodePudding user response:
I note the following:
fgets(sentence, 100, stdin);
... which I then note you're passing to KUlowerL
, so what's with the getchar
loop? You already did that work with the fgets
code, aye?
On the note of getchar
and tolower
, those two go together in a way that fgets
can't relate... You need to cast char
values to unsigned char
in passing to tolower
, where they'll be promoted to int
, whereas getchar
returns your character already cast for you, so no cast is necessary providing you keep that return value in an int
form...
CodePudding user response:
For starters it is a bad idea to use global variables like these
char sentence[100];
int count, ch, i;
and there is no any need to define them as global.
The function already got a string through its parameter. So rewriting it using calls of getchar
does not make a sense.
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 */
//...
Also the function does not change the processed string.
The function can be declared and defined the following way
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;
}
And in main the function can be called like
int main( void )
{
enum { N = 100 };
char sentence[N];
printf( "Bitte gebe deinen Satz ein: " );
fgets( sentence, N, stdin );
printf( "%s", KUlowerL(sentence) );
}
CodePudding user response:
You do not need this ?
operator. The function will change the case of the letter ignoring not letters.
ch = toupper((unsigned char)sentence[i]);
The below line makes no sense
for (i=0;(sentence[i] = getchar()) != '\n'; i );
You simply need to iterate through the string
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);
}
EDIT:
to swap case
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
CodePudding user response:
The reason it does not appear to work is that loop with getchar()
and you not expecting to type the sentence ZWEI MAL!!! You press RETURN and see nothing because the second "sentence" is zero characters long...
Gone over your code and made a few changes...
#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;
}
Output:
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
CodePudding user response:
to implement a function that will convert lowercase letters to uppercase letters and vice-versa.
Improve the case swap function
A string ends with a null character. A line of input ends with a
'\n'
. Better to create your function to work with a string and stop at a null character than a'\n'
Iterate through the string once. It is not necessary to first find the string length and then second convert. Do both together.
Remove user I/O code from
KUlowerL()
. Let calling code read data and print the text. OP's attempt to read 2 lines of input (once inmain()
and once inKUlowerL()
) causes trouble. It can explain the "when I use the code in the main it works when I try to put it in an function it doesn't work."is...(int ch)
andto...(int ch)
are well defined for values[0...UCHAR_MAX]
andEOF
, otherwise ifch < 0
, the result is undefined behavior (UB).str...()
functions perform as if access to strings was done viaunsigned char *
, even ifchar
is signed. This case conversion code should perform likewise.KUlowerL()
is a confusing name for a function that swaps case.Return something useful, like the string's beginning.
#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;
}
Test code
Use a local buffer.
Best to test the return value of input functions to determine if input succeeded.
#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().
}