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.
Related
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;
}
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.
I am quite newbie in c, so I just starting off with some code, experimenting some stuff, right now I am stuck with this problem in C, creating a function that displays the alphabet in lowercase, on a single line, by ascending order, starting from the letter ’a’.
This is where I am stuck:
#include <stdio.h>
int alfabet(unsigned int i) {
if(i <= 122) {
char litera = i;
return litera;
}
return alfabet(i+1);
}
int main() {
int i = 97;
printf(alfabet(i));
return 0;
}
Here, you won't print anything really interesting. In fact, your application will crash because printf() require at least a char * parameter (a string).
Your alfabet() function seems not so bad, but you should print the letter in it :
int alfabet(unsigned int i)
{
if (i > 'z') {
// Here is the stop condition.
// If the value is higher than 122 ('z' character), we stop recursivity)
return;
}
printf("%c ", i);
// Otherwise, let's call this function with another character
return alfabet(i+1);
}
Target simplicity
void alfabet(int c) {
printf("%c", c);
if (c < 'z') alfabet(c+1);
}
called from main as
alfabet('a');
You may add a printf("\n");
the function prints the character given as parameter
you only call recursively the function with the next character to be printed if necessary, i.e. if the current character is below z.
Something like that:
#include <stdio.h>
void alfabet(char i) {
if(i < 'z')
{
alfabet(i+1);
}
printf("%c", i);
}
int main() {
char i = 'a';
alfabet(i);
return 0;
}
to print zyxwvutsrqponmlkjihgfedcba. Or:
#include <stdio.h>
void alfabet(char i) {
printf("%c", i);
if(i < 'z')
{
alfabet(i+1);
}
}
int main() {
char i = 'a';
alfabet(i);
return 0;
}
to print abcdefghijklmnopqrstuvwxyz
As you are new in this language, the basic thing to know is that each and every character on the keyboard has its own ASCII value ranging from 000 to 127 (i.e. total 128).
Now if you want to print a to z in a single line, the ASCII value for 'a' is 97 and that for 'z' is 122.
So, for printing this on screen you need to learn the basic for loop structure.The syntax for basic for loop is as follows :-
for(expr1;expr2;expr3)
{
Body of the loop;
}
Here, expr1 refers to the initial value of the variable, expr2 refers to the exit condition of the loop and expr3 refers to the increment or decrement value.
So, the code to print a to z is as follows :-
#include<stdio.h>
#include<conio.h>
void main()
{
clrscr();
print_alpha();
getch();
}
void print_alpha()
{
int i;
for(i=97;i<+122;i++)
{
printf("%c",i);
}
}
int main() {
int i = 97;
printf("%c",alfabet(i));
return 0;
}
You Have to provide format specifier in printf (i.e. %c for character, %d for integer) Just check man printf in terminal.
And for printing a to z you can use for loop suggested by #Michel Jord, for printing in one line just put space in place of \n
#include <stdio.h>
void print_alphabets(char i) {
if(i>='a' && i<='z')
{
print_alphabets(i+1);
printf("%c ", i);
}
}
int main() {
char i;
scanf("%c",&i);
print_alphabets (i);
return 0;
}
I'm trying to make a program to decide the validity of a password, based on a set of rules.
Here is what I have:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int main()
{
int uppercase = 0;
int length = 0;
int numbers = 0;
int others = 0;
char password[13];
char yesOrNo;
printf("Your password must be 8-12 characters long.\n"
"It must contain at least one symbol, uppercase letter, and number.\n\n");
COMEBACK:
printf("Please enter your password:");
scanf(" %s", &password);
while (password != 'NULL') { // Tried 0 here, tried '\0', but to no avail.
if (isalpha(password)) {
length += 1;
if (isupper(password)) {
uppercase += 1;
}
}
else if (isdigit(password)) {
numbers += 1;
length += 1;
}
else {
length += 1;
}
// This is just a test, to see if it was working.
printf("%d - %d - %d - %d --- %s",
uppercase, length, numbers, others, password);
}
if ((uppercase > 0) && (numbers > 0)
&& (length >= 8) && (length <= 12) && (others > 0)) {
printf("Good job, you've done your password correctly.");
} else {
printf("%d - %d - %d - %d --- %s \t Incorrect..",
uppercase, length, numbers, others, password); // Same thing here.
scanf("%s", &yesOrNo);
switch (yesOrNo) {
case 'y':
goto COMEBACK;
break;
case 'n':
printf("Sorry you're dumb man..");
break;
default:
printf("Please enter a valid password.");
}
}
return 0;
}
The problem I am having is, the while loop never ends because it can't seem to find the terminator for my password array. I've inputted '\0' as well as just '0'. But I still can't figure it out. Any help is appreciated. Thanks.
This code:
while (password != 'NULL') {
should be generating compiler warnings galore. The multicharacter literal is non-portable and should not be compared with a pointer.
You might need:
char *ptr = password;
while (*ptr != '\0') {
...
ptr++;
}
or (C99 or later):
for (char *ptr = password; *ptr != '\0'; ptr++)
{
...
}
and use *ptr to identify the character (or, often, (unsigned char)*ptr since plain char is often signed and isalpha() et al require a positive value or EOF as the input value). If you don't have C99, you can declare char *ptr; outside the loop and remove the char * inside the loop control.
You have:
if (isalpha(password)) {
Since password is an array, you're passing a fixed pointer to a function that requires a non-pointer (int) value. I'd probably add inside the loop:
{
unsigned char uc = *ptr;
if (isalpha(uc))
...
Note that you probably only need one length++; for all the cases.
Also note that no password will ever satisfy the 'at least one symbol' criterion because you never increment others.
And the goto can be replaced by a while() loop which can detect EOF as well:
while (scanf("%12s", password) == 1)
{
length = others = uppercase = numbers = 0; // Ignore previous attempts
for (char *ptr = password; *ptr != '\0'; ptr++)
{
unsigned char uc = *ptr;
length++;
...character testing code...
}
...validity checking code...
}
While you're learning C, assume that the compiler warnings are solid errors. It knows more about C than you do at this stage.
password is an array. It will never be NULL. But it can contain a null-terminator, which is probably what you're after. Just check if password[0] == '\0'.
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 ...