Trying to return -1 or char - c

void main() {
int letter;
letter = myToLower('v');
printf("The new letter is: %c", letter);
}
int myToLower(char ch) {
if (isupper(ch)) return tolower(ch); else return -1;
}
when im trying Upper Case the program works and return the letter in lower case, when im trying lower case the program doesnt return -1.
someone have an idea how can i return both of them?

The problem is that you are returning a -1 value, and when printf looks at the %c in it, it looks at the corresponding valist argument, and it finds -1. The output of this is system dependant. The fix is this: (as given by Eljay)
if (letter != -1)
{
printf("The new letter is: %c\n", letter);
}
else
{
printf("The letter is unchanged.\n");
}
It is usually best to but in braces because it is more debuggable that way. You can see where the statements start and end.

Related

Output not showing in C

I'm writing a code that must identify the letter 't' or 'T' in a word, before or after the middle of it.
If the first half of the word does contain a 't' or a 'T', the program should output a 1. If the first half does not contain the letter 't' or 'T', but the second half does, then the program should output a 2. Otherwise, if there is no 't' or 'T' in the word at all, the program's output should be -1. The word entered will not have more than 50 letters.
#include <stdio.h>
#include <string.h>
int main() {
char word[50];
int i = 0, length, t = 0, T = 0;
scanf("%s", word);
length = strlen(word);
t = word[i] == 't';
T = word[i] == 'T';
while(!t || !T) {
if((t || T) && i <= length / 2) {
printf("%d", '1');
} else if((t || T) && i > length / 2) {
printf("%d", '2');
//}else{
// printf("%d", '-1');
}
i++;
}
return 0;
}
If I enter any word and press enter, nothing is printed. Another thing is that when I remove the comment slashes from the two lines at the bottom, the program goes through an infinite loop.
Could someone please help?
This sounds like a school assignment, so I'll focus on advising/critiquing your code rather than giving a solution.
The first recommendation I have is to use a for loop instead of a while loop. A Rule of thumb in C is to only use a while loop when you actually don't have any idea how many things you need your program to look at.
You already have the length of the string, so set up your for loop to loop exactly once for each character.
Next you need to change how you are using printf. The %d format specifier is for printing integers, but you are passing it '1'. This is not an integer, it is the ascii representation of the symbol 1 (which is actually has the value 49, see the ascii table for more info)
You can either pass printf the value 1, or use the %c specifier, which expects ascii characters.
Better yet, just say printf("1");
That doesn't get you all the way there, but I think it lays the ground work so you can find the solution!
Condition !t || !T has no sense to be used as loop condition ...ask yourself how the loop will end ? you need just to check i is less than length
Second, the assignments t = word[i] == 't'; T = word[i] == 'T'; outside the loop have no sense ...you will be just pointing to the zero index of the string ...you should check all characters
third , the printf lines need to use %d
fourth , you appear not getting the purpose of the program printing inside loop will lead to printing many numbers and you just want to know if there is t or T you need to print single line.you may use variable int result=0; to hold the value you want and print it in the end ...of course you will need using break statement in the if((t || T) && i <= length / 2) and if((t || T) && i > length / 2) because no need for more searching
fifth, you should re-read , re-think , re-code the assignment before going bored and asking about it
sixth, there is a working version by modifying your code but you should try writing a good solution before looking at a solution as it better to solve your problems by yourself
#include <stdio.h>
#include <string.h>
int main() {
char word[50];
int i = 0, length, t = 0, T = 0;
scanf("%s", word);
length = strlen(word);
int result=0;
while( i<length) {
t = word[i] == 't';
T = word[i] == 'T';
if((t || T) && i <= length / 2) {
result=1;
break;
} else if((t || T) && i > length / 2) {
result=2;
break;
}else{
result=-1;
}
i++;
}
printf("%d",result);
return 0;
}
# include <stdio.h>
int main()
{
char name[20];
int age;
int siblings;
int childrens;
printf ("Hello my name is A.I, what is your name? \n");
scanf("%s", &name);
printf("how old are you : \n");
scanf("%d",&age);
printf("how many siblings you have: \n");
scanf("%d", &siblings);
printf("how many children you have: \n");
scanf("%d", &childrens);
printf("so your name is : %s \n", name);
printf("and your age is : %d \n", age);
printf("you have siblings : %d\n", siblings);
printf("so you have childrens : %d\n", childrens);
return 0;
}

How to loop through a users input using getchar() and check to see if the characters are an alphabet or a digit

Im totally new to programming, I picked up a C manual to learn on my own. I dont want to use an array as Im trying to practice with getchar(). I want to be able to output an error message if the user enters anything other than a digit or an alphabet. I am also trying to practice the C library function isalpha() and isdigit(). This is what I wrote so far, but my output is not quite right.
Input 1: "hello"
Expected output : "valid output"
Input 2: "hello5"
Expected output : "valid output"
Input 3: "hello!"
Expected output : "invalid output"
But my program returns "valid input" for all the three inputs above
Please help a newbie try to learn. I greatly appreciate it.
#include <stdio.h>
#include <ctype.h>
int main ()
{
char ch;
int len;
int valid;
printf("Enter a word: ");
for(length = 0; (ch = getchar()) != '\n'; len++)
{
if(isalpha(ch) || isdigit(ch))
{
valid = 1;
}
else
{
valid = 0;
}
}
printf("Input length: %d\n", len);
if (valid == 1)
{
printf("Valid\n");
}
if(valid == 0)
{
printf("\n");
}
return 0;
}
You were almost there. Few pitfalls:
1st there is a typo for your variable name “length” instead of “len”.
2nd As Mitchel0022 stated, your program will always display “valid” providing the last character entered is valid because you reassign a new value for the variable ‘valid’ on each iteration. but you don’t have to use a ‘break statement since you need the loop to continue in order to get your length, so stick with your flag.
Now your program should run fine. Copy and paste the code below:
#include <stdio.h>
#include <ctype.h>
int main ()
{
char ch;
int len;
//flag is set true
int valid = 1;
printf("Enter a word: \n");
for(len = 0; (ch = getchar()) != '\n'; len++)
{
//change flag if character is not number nor letter
if(!isalpha(ch) && !isdigit(ch))
{
valid = 0;
}
}
printf("Input length: %d\n", len);
if (valid == 1)
{
printf("Valid\n");
}
else
{
printf("Invalid\n");
}
return 0;
}
The error here is when checking every character, by toggling valid to 0 and 1 really you are only looking at the last character. What you want to do is for every character as soon as you find one character that is not a digit/alpha character then exit
you can replace your if/else with something like this
vlaid = 1; //always assume its valid
for(int length = 0; (ch = getchar()) != '\n'; length++)
{
if(!isalnum(ch)) //if not a valid character
{
valid = 0; // string is not valid anymore
break; // we can exit the loop
}
}

two functions are occurring at the same time

I have to create a program that creates a guess the letter game.
Everything is built successfully. However, I run into a problem because the GetTheLetter function and the CompareThe Letters function are combining and printing at the same time. When it prompts the user for a guess, it is also printing out the first if statement of the CompareTheLetters function. What am I doing wrong?
#define _CRT_SECURE_NO_WARNINGS
#define MAXGUESSES 4
#include <stdio.h>
void GuessItRules(); //Game instructions
int PlayOneGame(char letter); //Runs a game
char GetTheLetter(); //Prompts user to guess and returns guess
int IsAWinner(char letter, char userguess); //Returns either a 1 or a 0 depending on if the user guessed correctly
void CompareTheLetters(char letter, char userguess); //Prints message dependent on whether guess comes before, after, or is the letter
int main()
{
//declare additional variables
//declare FILE pointer
FILE* PTR;
int numOfgames; //number of games user wants to play
int i; //iterator
char letter; //letter from file
int win; //variable for the return of the PlayOneGame function
//display instructions
GuessItRules();
//connect to the file HINT: use fopen
PTR = fopen("letters.txt", "r");
//get number of games to play
printf("Let's start playing!\n\nHow many games would you like to play (1-5)?\n\n");
scanf("%d", &numOfgames);
//this for loop will allow the player to play more than one game
//without recompiling
for (i = 0; i < numOfgames; i++)
{
//get a letter from file - use fscanf
fscanf(PTR, "%c", &letter);
//Play one game (Call PlayOneGame function) - remember the function has an int return type
win = PlayOneGame(letter);
//tell the player if they have won or lost (test the variable win)
if (win == 1)
printf("Congrats! You guessed the correct letter!!\n\n");
else if (win == 0)
printf("I'm sorry you did not guess the correct answer :( The letter was %c\n\n", letter);
}
//close file
fclose(PTR);
return 0;
}
//Function definitions
void GuessItRules()
{
printf("Welcome to the Guess the Letter Game!\n-------------------------------------\n\n");
printf("You will have 4 chances to guess the letter per a game\n\n");
}
int PlayOneGame(char letter)
{
int numOfguesses = 0;
int winOrLose = 0; //should be intialized
char userguess; // user guess
//As long as the user has not used up the maximum number
//of guesses and has not guessed correctly
//the game will continue using this while loop
while (numOfguesses < MAXGUESSES && winOrLose == 0)
{
//function call to GetTheletter - returns to userguess variable
userguess = GetTheLetter();
//function call to IsAWinner - returns to winOrLose variable (0 or 1)
winOrLose = IsAWinner(letter, userguess);
//function call to CompareTheLetters - gives the user a message
CompareTheLetters(letter, userguess);
//update counter for number of guesses used
numOfguesses = numOfguesses + 1;
}
return winOrLose; //(0 or 1)
}
char GetTheLetter()
{
char userguess;
printf("Please enter a guess \n\n");
scanf("%c", &userguess);
return (userguess);
}
int IsAWinner(char letter, char userguess)
{
if (userguess == letter)
return (1);
else
return (0);
}
void CompareTheLetters(char letter, char userguess)
{
if (userguess < letter)
{
printf("The letter you are trying to guess comes after %c\n\n", userguess);
}
else if (userguess > letter)
{
printf("The letter you are trying to guess comes before %c\n\n", userguess);
}
else if (userguess == letter)
{
printf("The letter is %c!!!!\n\n", userguess);
printf("Congrats!!! You did it!!\n\n");
}
}
The problem lies in when you ask the user for a letter to guess.
When you use the %c format specifier to scanf, a newline satisfies this format specifier. Since there will have been a newline left in the input buffer from your previous input, this picks up that newline.
Put a space at the beginning of the format string to absorb the newline:
scanf(" %c", &userguess);
Note that other format specifiers such as %d and %f will skip over newlines, unlike %c. So the leading space to skip newlines is needed only for %c.

Inverting Capitalization of letter in C

ok so i was asked to invert capitalization in C using a function inver_caps. My function works and prints the new letter correctly, but im having trouble as to why in the main it will not print correctly?
Any ideas?
void invert_caps (char letter);
int main(void){
char lettermain;
printf("Enter a letter: ");
scanf(" %c", &lettermain);
invert_caps(lettermain);
printf("The invert of the letter is %c \n", lettermain);
system("PAUSE");
return 0;
}
void invert_caps (char letter){
printf("\nletter is %d\n",letter); /*this was used for debugging*/
if ((int)letter >=65 && (int)letter<=90){
letter = (int)letter+32;
}else{
letter = (int)letter - 32;
}
printf("\nnew letter is %d or %c\n",letter, letter); /*this was used for debugging*/
return letter;
}
You are doing pass by value (copy value), that doesn't reflects change made in calling at caller function. Do
(1) pass by pointer (pass address), Or
(2) simply return converted value from function.
Side note: Don't use ascii values in code, just use char constants to keep code readable (you don't have to remember ascii value).
For example I write (2) solution for you (I believe that will be easy for you presently, avoiding pointer at this stage).
to understand the code read comments:
char invert_caps (char letter){
// ^ added return type, its not void now
if ( letter >= 'A' && letter<= 'Z'){ // not using ASCII value but char Constants
letter = letter + ('a' - 'A'); // its more readable
// Note 32 = 'a' - 'A' that is 97 - 54
}
else {
if ( letter >= 'a' && letter<= 'z'){// Add this case, to be safe is good practice
letter = letter - ('a' - 'A');
}
else
letter = '\0'; // if letter is neither Upper or lower alphabetic case
} // then convened it into nul symbol (exception case)
return letter; // added a line
}
// I removed unnecessary typecasts and debug statements
In main() you need to call it like at same place:
lettermain = invert_caps(lettermain);
// ^ return value assigned to variable `lettermain`
return is a key word in C. The return statement terminates the execution of a function and returns control to the calling function. A return statement can also return a value to the calling function and from function invert_caps() we are returning converted value.
Here is a small routine using library functions to detect and change letter case.
#include <ctype.h>
int invert_case(int c)
{
return islower(c) ? toupper(c) : isupper(c) ? tolower(c) : c;
}
If you don't like the nested ?: ternary operators, here is the same logic using if.
int invert_case(int c)
{
if (islower(c)) {
return toupper(c);
}
if (isupper(c)) {
return tolower(c);
}
return c;
}
Note: this can be made even simpler, see Dave's comment below.
basic reason you are not getting the inversion in the main method is you are only passing a copy of lettermain to invert_caps() method.
Rather than that do the following,
void invert_caps (char letter);
int main(void){
char lettermain;
printf("\n=========Question 8=========\n");
printf("Enter a letter: ");
scanf(" %c", &lettermain);
lettermain=invert_caps(lettermain);
printf("The invert of the letter is %c \n", lettermain);
system("PAUSE");
return 0;
}
char invert_caps (char letter){
printf("\nletter is %d\n",letter);
if ((int)letter >=65 && (int)letter<=90){
letter = (int)letter+32;
}else{
letter = (int)letter - 32;
}
printf("\nnew letter is %d or %c\n",letter, letter); /*this was used for debugging*/
return letter;
}
Because when you pass the lettermain variable from main, it's copied.
You need to either return the new character, or pass the variable by reference.

Accented/umlauted characters in C?

I'm just learning about C and got an assignment where we have to translate plain text into morse code and back. (I am mostly familiar with Java so bear with me on the terms I use).
To do this, I have an array with the strings for all letters.
char *letters[] = {
".- ", "-... ", "-.-. ", "-.. ", ".", "..-." etc
I wrote a function for returning the position of the desired letter.
int letter_nr(unsigned char c)
{
return c-97;
}
This is working, but the assignment specifications require the handling of the Swedish umlauted letters åäö. The Swedish alphabet is the same as the English with these three letters in the end. I tried checking for these, like so:
int letter_nr(unsigned char c)
{
if (c == 'å')
return 26;
if (c == 'ä')
return 27;
if (c == 'ö')
return 28;
return c-97;
}
Unfortunately, when I tried testing this function, I get the same value for all of these three: 98. Here is my main, testing function:
int main()
{
unsigned char letter;
while(1)
{
printf("Type a letter to get its position: ");
scanf("%c", &letter);
printf("%d\n", letter_nr(letter));
}
return 0;
}
What can I do to resolve this?
The encoding of character constants actually depend on your locale settings.
The safest bet is to use wide characters, and the corresponding functions. You declare the alphabet as const wchar_t* alphabet = L"abcdefghijklmnopqrstuvwxyzäöå", and the individual characters as L'ö';
This small example program works for me (also on a UNIX console with UTF-8) - try it.
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main(int argc, char** argv)
{
wint_t letter = L'\0';
setlocale(LC_ALL, ""); /* Initialize locale, to get the correct conversion to/from wchars */
while(1)
{
if(!letter)
printf("Type a letter to get its position: ");
letter = fgetwc(stdin);
if(letter == WEOF) {
putchar('\n');
return 0;
} else if(letter == L'\n' || letter == L'\r') {
letter = L'\0'; /* skip newlines - and print the instruction again*/
} else {
printf("%d\n", letter); /* print the character value, and don't print the instruction again */
}
}
return 0;
}
Example session:
Type a letter to get its position: a
97
Type a letter to get its position: A
65
Type a letter to get its position: Ö
214
Type a letter to get its position: ö
246
Type a letter to get its position: Å
197
Type a letter to get its position: <^D>
I understand that on Windows, this does not work with characters outside the Unicode BMP, but that's not an issue here.
In general encoding stuff is quite complicated. On the other hand if you just want a dirty solution specific to your compiler/platform than add something like this to your code:
printf("letter 0x%x is number %d\n", letter, letter_nr(letter));
It will give hex value for your umlauts. Than just replace in if statements your letter with number.
EDIT You say that you are always getting 98 so your scanf got 98 + 97 = 195 = 0x3C from console. According to this table 0x3C is start of UTF8 sequence for common LATIN SMALL LETTER N WITH Something in Latin1 block. You are on Mac OS X ?
EDIT This is my final call. Quite hackery but it works for me :)
#include <stdio.h>
// scanf for for letter. Return position in Morse Table.
// Recognises UTF8 for swedish letters.
int letter_nr()
{
unsigned char letter;
// scan for the first time,
scanf("%c", &letter);
if(0xC3 == letter)
{
// we scanf again since this is UTF8 and two byte encoded character will come
scanf("%c", &letter);
//LATIN SMALL LETTER A WITH RING ABOVE = å
if(0xA5 == letter)
return 26;
//LATIN SMALL LETTER A WITH DIAERESIS = ä
if(0xA4 == letter)
return 27;
// LATIN SMALL LETTER O WITH DIAERESIS = ö
if(0xB6 == letter)
return 28;
printf("Unknown letter. 0x%x. ", letter);
return -1;
}
// is seems to be regular ASCII
return letter - 97;
} // letter_nr
int main()
{
while(1)
{
printf("Type a letter to get its position: ");
int val = letter_nr();
if(-1 != val)
printf("Morse code is %d.\n", val);
else
printf("Unknown Morse code.\n");
// strip remaining new line
unsigned char new_line;
scanf("%c", &new_line);
}
return 0;
}
Hmmm ... at first I'd say the "funny" characters are not chars. You cannot pass one of them to a function accepting a char argument and expect it to work.
Try this (add the remaining bits):
char buf[100];
printf("Enter a string with funny characters: ");
fflush(stdout);
fgets(buf, sizeof buf, stdin);
/* now print it, as if it was a sequence of `char`s */
char *p = buf;
while (*p) {
printf("The character '%c' has value %d\n", *p, *p);
p++;
}
Now try the same with wide characters: #include <wchar.h> and replace printf with wprintf, fgets with fgetws, etc ...

Resources