lower case to Uppercase function - C - c

I've written this function to convert a lowercase str that is preset into it's uppercase variant. I've tried every different configuration I know that converts lower case to uppercase, however when I print it. It still ends up in lower case. So I am a tad Stuck.
char* stoupper(char str[]);
char str[100]= "uppercase";
printf("%s" , stoupper(str)); // Test to make sure it is working
char* stoupper(char str[])
{
int i = 0;
while(str[i] != '\0')
{
if(str[i] >= 'A' && str[i] <= 'Z')
str[i] = str[i] + ('A' - 'a');
i++;
}
return str;
}
/* I've tried various variations of this function this is just the one i had first */

Your code only modifies already-uppercase letters, and turns them into who-knows-what (well, I'm sure you could figure out with an ASCII table). If you want to operate on lowercase letters, you need to change your if condition:
if (str[i] >= 'a' && str[i] <= 'z')

why are you reinventing the wheel? ctype.h is your friend
Use the toupper(int) method. Something like
char* stoupper(char str[]);
char str[100]= "uppercase";
printf("%s" , stoupper(str)); // Test to make sure it is working
char* stoupper(char str[])
{
int i = 0;
while(str[i])
{
str[i]=toupper(str[i]);
i++;
}
return str;
}

I think your if condition should be:
if(str[i] >= 'a' && str[i] <= 'z')

your condition in if statement needs to be changed
if(str[i] >= 'A' && str[i] <= 'Z')
May I suggest another way to change Uppercase to lowercase and vice-versa
char* stoupper(char str[])
{
for(int i=0;i<strlen(str);i++)
if(!(str[i]>='A'&&str[i]<='Z')){
str[i]=str[i]^' ';
}
return str;
}
this method works because
[ASCII value of a lowercase character] XOR [ASCII value of ' '] =[ASCII value of that same character in UPPERCASE ]

Related

How to use ASCII codes to create uppercase strings in C programming language

I have a function in C as follows
char *ft_strupcase(char *str)
{
int i;
i = 0;
while (str[i] != '\0')
{
if (str[i] >= 'a' && str[i] <= 'z')
{
str[i] -= 32;
}
i++;
}
return (str);
}
which converts lowercase letter in the string to upper case. I want to achieve the same but using ASCII values instead. My code is
char *ft_strupcase(char *str)
{
int index;
index = 0;
while (str[index] != '\0')
{
if (str[index] < 97 && str[index] < 122)
{
str[index] = str[index] - str[32];
}
++index;
}
return str;
}
which gives me a error
Bad permissions for mapped region at address 0x400657at 0x40057B: ft_strupcase 
which I don't understand why. According to my understanding if the char on the string is "a" then my code should convert it to "A" as 97 -32 = 65 which is an ASCII for A . I am lost as to what I am doing wrong. Any guidance is highly appreciated
Insure str does not point to a string literal
char *bad = "Test";
ft_strupcase(bad); // UB
char good[] = "Test";
ft_strupcase(good); // OK
Wrong compare
Wrong offset
str[32] is not the difference between lower and upper case ASCII characters. That is some element of array str[].
Avoid naked magic numbers
//if (str[index] < 97 && str[index] < 122) {
// str[index] = str[index] - str[32];
//}
#define ASCIIA 65
#define ASCIIa 97
#define ASCIIz 122
if (str[index] >= ASCIIa && str[index] <= ASCIIz) {
str[index] = str[index] - ASCIIa + ASCIIA;
}
It really makes more sense to use 'a' instead of ASCIIa or 97. Same for the other constants.
The only reason for not using 'a' is to make the source code portable to non-ASCII source code environments (rare these days) yet still handle ASCII input.

Find spaces and alphanumeric characters in a string C Language

Hi i'm trying to build a function in C language that checks if the string contains numbers , upper cases and lower cases and space, if the string contains any other character then those the function return -1.
float avg_word_len(char* str)
{
float check;
for (int i = 0; i < strlen(str); i++)
{
if (((str[i] >= '0') && (str[i] <= '9')&&(str[i] >= 'a') && (str[i] <= 'z') && (str[i] == ' ')&& (str[i] >= 'A') && (str[i] <= 'Z')))
check = 1;
else
check = -1;
}
str = '\0';
return check;
that's my code ,but the function keep return -1 please help
Some of your && must replaced by || because one character is a number OR a lower case OR a space OR an upper case, but it cannot be all these things at a time :
check = 1;
for (int i = 0; i < strlen(str); i++)
{
if (! (((str[i] >= '0') && (str[i] <= '9')) ||
((str[i] >= 'a') && (str[i] <= 'z')) ||
(str[i] == ' ') ||
((str[i] >= 'A') && (str[i] <= 'Z')))) {
check = -1;
break;
}
}
You can use these three function which are countain in the hreader #include <ctype.h>
isalpha : Checks if a character is alphabetic (upper or lower case).
isdigit : Checks if a character is a number.
isblank : Checks whether a character is blank or not.
#include <ctype.h>
#include <stdio.h>
float avg_word_len(char* string)
{int check=-1;
for(int i=0;string[i]!='\0';i++)
{
if(isalpha(string[i])||isdigit(string[i])||isblank(string[i]))
{
check=1;
}
}
return check;
}
int main()
{
char string[150];
printf("Give me a text :");
scanf("%s[^\n]",string);
printf("\n%.f\n",avg_word_len(string));
}
As Weather Vane commented, a lot of those &&s should be ||s - additionally, parentheses should surround each range (e.g. ('0' <= str[i] && str[i] <= '9'))).
To check whether the character is in a range, we use AND (i.e. the character is above the lower bound AND below the upper bound). To check whether the character is in one of multiple ranges, we use OR (i.e. the character is in range 1 OR it is in range 2 OR...).
If we were to only fix that, here's how the if condition would look:
(str[i] >= '0' && str[i] <= '9') || (str[i] >= 'a' && str[i] <= 'z') || (str[i] == ' ') || (str[i] >= 'A' && str[i] <= 'Z')
Having said that, I would suggest using the function isalnum from ctype.h in the standard library, which checks if a character is alphanumeric. It makes the code much simpler and avoids the assumption that characters are ordered in such a way that all lowercase letters lie between 'a' and 'z' (which is true in ASCII - which is what is used in practice - but is not standard).
In addition, I would suggest initializing check to -1 and breaking early from the loop once you find a non-alphanumeric, non-space character so that a -1 is not later overwritten by a 1 (as would happen in the current version of your code).
This is what it would look like:
float check = -1;
for (int i = 0; i < strlen(str); i++)
{
if (!isalnum(str[i]) && str[i] != ' ') {
check = 1;
break;
}
}

How to change numbers in an array to symbols

I am trying to find a good way to convert digits of a string in an array to a # symbol.
I would like to be clear, this is for a homework assignment. I am asking for help because not only am I running into roadblocks that I would like to overcome; but I want to understand the relationship between arrays and functions as well.
I have done some code, shown below, but I feel like I am confusing myself on the relationship between calls in arrays when they are within a function.
Here is what I have done:
void coverNumbers(char s[]) {
char num;
if (s[num] >= '0' || s[num] <= '9')
num = '#';
}
I feel like I am so close to having a solution.
If I type in 43ll0 within the array, I want the 43ll0 to become ##ll#.
Thank you for your help everyone, and have a wonderful night!
You are going about this the wrong way. You need to loop over the string to check and replace each character individually.
Try This
void coverNumbers(char s[]) {
for (int i = 0; s[i]; i++)
if (s[i] >= '0' && s[i] <= '9')
s[i] = '#';
}
You have additional logic mistakes. If you have some questions on why I changed a specific thing please ask in the comments.
Assuming covernumbers receives a C string, ie a pointer to a char array terminated by a null byte '\0', you should just iterate on all characters and perform the modification. Note however that you used || instead of && to test for digits. s[num] is a digit if it is >= '0' and <= '9'.
Here is a corrected version:
void coverNumbers(char s[]) {
for (size_t i = 0; s[i] != '\0'; i++) {
if (s[i] >= '0' && s[i] <= '9')
s[i] = '#';
}
}
You can also use the pointer and increment it. void coverNumbers(char s[]) and void coverNumbers(char *s) are equivalent and the second version make it more obvious that s is a pointer, not an actual array.
void coverNumbers(char *s) {
while (*s) {
if (*s >= '0' && *s <= '9')
*s = '#';
s++;
}
}
Welcome to Stack Overflow!
You should not use stack overflow for such kind of problems. But you can always ask questions on the issues you are facing, if the similar question is not already been asked by others.
SOLUTION:
Algorithm:
Get the length of the string
Iterate each character in the string
Based on the value in current position (index) of string, replace with '#' if it's a digit.
Print the output
Code:
void coverNumbers(char s[]) {
int len = strlen(s);
for (int i = 0; i < len; i++)
if (s[i] >= '0' && s[i] <= '9')
s[i] = '#';
printf("%s", s);
}

How to determine if user input is an number using a boolean function in C

I am trying to figure out how to determine if the user input is a number and not a letter/symbol (A,a,!,#,#,$,%) in C, using a boolean function. The code I am using (if statement) only works for lower case and capitals letters. Below is my code for the if statement that works. Below that I will include the boolean function I am (unsuccessfully) attempting. Am I missing something in my boolean function?
if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')){
printf("Character '%c' does not represent a digit\n", ch);}
_Bool isNumber(char ch) {
printf("Character '%c' does not represent a digit\n", ch);
return 0;}
Is it possible without a library function?
The C standard library already has such a beast:
#include <ctype.h>
:
if (! isdigit(ch)) {
printf("'%c' is not a digit\n", ch);
}
If, for some bizarre reason(a) you cannot use the standard library function, simply roll your own:
bool isDigit(int ch) { // Uppercase D to distinguish it.
return ch >= '0' && ch <= '9';
}
You can also do it directly in the code rather than as a function:
if (ch < '0' || ch > '9') puts("Not a digit"); // or:
if (ch >= '0' && ch <= '9') puts("Is a digit");
The digit characters in C are guaranteed by the standard to be contiguous, unlike all the other characters. That's why doing the same for alphas (like ch >= 'a' && ch <= 'z') is a bad idea.
Keep in mind that's for a single character being a digit. That appears to be what you want. To check if a character string is a valid integer, it'll need to be more complex. Basically, every character will need to be a digit, and it may have an optional sign at the front. Something like this would be a good start:
bool isInt(char *sstr) {
unsigned char *str = sstr;
if (*str == '+' || *str == '-')
++str;
if (! isdigit(*str++)) // or your own isDigit if desired.
return false;
while (*str != '\0')
if (! isdigit(*str++)) // ditto.
return false;
return true;
}
(a) Though I suppose you may want to do it for educational purposes, so not necessarily that bizarre :-)
If you want to stay true to your original logic, if(ch >= '0' && ch <= '9')) will be true if ch is any digit and false for any other character.

Function to check for alphabetic characters

I created a Function to check if user typed a Real Name excluding all other non alphabetic characters.
Well, from my side, as a beginer in C language its works fine.
Anyway i have just a small problem, with the string name, if there is space inside that string i get wrong Name, but if there is only one name (michi) everything is ok.
#include <stdio.h>
#include<string.h>
/* Here is the Function which check if the string contains only: */
/* abcdefghijklmnopqrstuvwxyz and ABCDEFGHIJKLMNOPQRSTUVWXYZ */
int checkName(char *s){
int i,length;
length = (strlen(s));
for (i=0;i<length;i++){
if(s[i] == '0' || s[i] <= '9'){
return 1;
}
}
return 0;
}
int main(){
char name[]= "Michi";
int check;
if((check = checkName(name)) == 0){
printf("\n\n\t\t\tYour name is:\t%s\n\n",name);
}else{
printf("\n\n\t\t\tWrong name:\t%s\n\n",name);
}
return 0;
}
My questions are:
1)
Did i found a right way of checking if string contains only non alphabetic characters.
2)
How can i extend my Function to skip spaces
Take a look at isalpha in ctype.h. This returns true if a char is a letter, just like what you want.
http://www.cplusplus.com/reference/cctype/isalpha/
By the way, if you're checking ASCII encodings, your function fails for characters such as '(' or '~'.
Here is the Function which check if the string contains only:
abcdefghijklmnopqrstuvwxyz and ABCDEFGHIJKLMNOPQRSTUVWXYZ
Looking at the code below that statement, you're lying. What your code does is checking whether there is a character 0 or any character below 9 in the string. Better do what you're saying:
if((str[i] >= 'a' && str[i] <= 'z') ||
(str[i] >= 'A' && str[i] <= 'Z') ||
(str[i] == ' ')) {
// fine ..
}
else {
// not fine!
}
As you see I added the space to the set of allowed characters. To get rid of the if branch just negate the whole test expression (either by hand or using the not operator !).
The comparisons are working this way because of the layout of the ASCII table.
Note that there's a library function for this: isalpha
If you have a valid set, test against this set, not other sets that might or might not be the complement set (So many sets in one sentence :-):
for (i=0; i<length; i++) {
int valid = 1;
valid &= s[i] >= 'a' && s[i] <= 'z';
valid &= s[i] >= 'A' && s[i] <= 'Z';
valid &= s[i] == ' ';
if (!valid) {
return 0; // or any value you prefer to indicate "not valid"
}
}
If you want to check only alphabetic chars and space, you can use isapha and isspace from ctype.h. These functions return non-zero for ture and zero for false.
You can just continue the loop if the character is a space:
for (i=0;i<length;i++){
if(s[i] == ' '){
continue;
}
else if(s[i] == '0' || s[i] <= '9'){
return 1;
}
}
Furthermore, you could also make sure it does not contain any other character than just alphabetic, by checking if all character are not outside the range of accepted characters:
for (i=0;i<length;i++){
if((s[i] < 'A') || (s[i] > 'Z' && s[i] < 'a') || (s[i] > 'z')){
return 1;
}
}
Note: the ASCII table is a nice "tool" to confirm the range you have to check.

Resources