I have a relatively simple problem. A user is supposed to run the program,type in a message of 30 characters or less and then the case of the individual letters of the messages will be toggled.(lowercase letters will be made upercase and vice versa). Everything is fine except for the part of changing the case. I am supposed to use a pointer to a char in an array and pass it as a function argument to toggle_case. Please assist me on how to achieve this.
Here is the code.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
void read_message(char *message, int *message_size);
void toggle_case(char *character);
void count_cv(char* message);
int main() {
char message[30];
int message_size;
char *message_pointer;
message_pointer = message;
read_message(message, &message_size);
int i = 0;
for(i =0; i<30; i++){
toggle_case(&message_pointer[i]);
}
printf("New string: %s",message);
return 0;
}
void read_message(char *message, int *message_size){
printf("Enter your string (maximum 30 characters): ");
fgets(message, 30, stdin);
}
void toggle_case(char *character){
//check if character is a letter
if (isalpha(*character)) {
//Check if the character is upper case
if(isupper(*character)){
//convert the character to lower case
tolower(*character);
} else {
//Check if the character is lower case
//convert the character to upper case
toupper(*character);
}
}
}
void count_cv(char* message){
}
tolower and toupper return the new character, you need to assign it back to the location you're updating.
if (isupper(*character)) {
*character = tolower(*character);
} else {
*character = toupper(*character);
}
BTW, you don't need to check if the character is a letter first. tolower and toupper will simply return the character unchanged if it's not a letter.
Related
i'm practicing strings now and what i try to do in this program is print something like: hello world into HellO WorlD as an output.
My code is the following one:
#include <stdio.h>
#include <string.h>
void convertir(char cadena[200]){
int length = strlen(cadena);
int i;
printf("%c", cadena[0]-32); // Prints letter in caps
for(i=1;i<length-1;i++){
if(cadena[i] == ' '){ // Search if there is space
printf("%c", cadena[i-1]-32);
i=i+1; // Adds vaule on i with accumulator to make caps the letter after the space
printf(" %c", cadena[i]-32); // prints letter in caps after space
} else {
printf("%c", cadena[i]); // prints everything in the string
}
}
printf("%c", cadena[length-1]-32);
}
int main(int argc, char const *argv[]) {
char cadena[200];
printf("Introduce un texto: ");
gets(cadena);
convertir(cadena);
return 0;
}
What the code compiled returns me after typing hello world is: HelloO WorlD, i'm trying to replace that o in HelloO but i'm getting confused...
Any help is appreciated.
Thank you.
I made the following changes to your for loop and it appears to work as you expect it to:
for(i=1;i<length-1;i++)
{
if(cadena[i + 1] == ' ') /*** Look If Next Character Is A Space ***/
{
printf("%c", cadena[i]-32); /*** Print Current Character In Uppercase ***/
i=i+1; // Adds vaule on i with accumulator to make caps the letter after the space
printf(" %c", cadena[i + 1]-32); /*** Print Character After Space In Caps ***/
i=i+1; // Adds vaule on i with accumulator to make caps the letter after the space
}
else
{
printf("%c", cadena[i]); // prints everything in the string
}
}
Output:
$ ./main.exe
Introduce un texto: hello world
HellO WorlD
Moving forward, there are several things you should do to make your program more robust:
Don't assume there aren't leading spaces (or whitespace)
Don't assume each character is lowercase
Don't assume each character is a letter
Don't assume there is only one space (or whitespace) between words
Any help is appreciated.
Use isalpha() to detect if a char is part of a word.
Use toupper() to convert to an uppercase character.
Use unsigned char for isalpha(), toupper() to avoid UB with negative char values.
Employ a boolean to keep track if a beginning of a word is possible.
#include <ctpye.h>
#include <stdbool.h>
void convertir(const char *cadena) {
const unsigned char *s = (const unsigned char *) cadena;
bool potential_start_of_word = true;
while (*s) {
// If next character is not an alpha or we area at the start of a word ...
if (!isapha(s[1]) || potential_start_of_word) {
printf("%c", toupper(*s));
} else {
printf("%c", *s);
}
potential_start_of_word = !isapha(*s);
s++;
}
}
No need for strlen(cadena)
You can use ctype.h's toupper() function or provide your own implementation. Something like this:
int toupper(int c) {
return (c-32);
}
And then use it like this:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void convertir(char cadena[200]){
int length = strlen(cadena);
int i;
cadena[0] = toupper(cadena[0]);
cadena[length-1] = toupper(cadena[length-1]);
for(i=0; i<length; i++){
if(cadena[i] == ' '){ // Search if there is space
cadena[i-1] = toupper(cadena[i-1]);
if (i+1 < length) cadena[i+1] = toupper(cadena[i+1]);
}
}
printf("%s\n", cadena);
}
int main(int argc, char *argv[]) {
char cadena[200];
printf("Introduce un texto: ");
gets(cadena);
convertir(cadena);
return 0;
}
How can I check whether there are numbers in char provided by user in C language?
Last line of C code to change :):
char name;
do{
printf("What's your name?\n");
scanf("%s\n", name);
}
\\and here's my pseudocode:
while (name consist of a sign (0 or 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9));
Here is a different approach that tests for specified chars in one function call.
#include <stdio.h>
#include <string.h>
int main()
{
char name[100];
char charset[]= "-+0123456789";
int len;
do {
printf("What's your name?\n");
scanf("%s", name);
len = strlen(name);
}
while (strcspn(name, charset) != len);
printf ("Your name is '%s'\n", name);
return 0;
}
You need to include ctype.h and use the isdigit() function.
But you also have another porblems in the posted code, "%s" specifier expects a char pointer, and you are passing a char, may be what you need is a char array like this
#include <stdio.h>
#include <ctype.h>
int main()
{
char name[100];
int i;
do {
printf("What's your name?\n");
scanf("%s\n", name);
}
/* and here's my pseudocode: */
i = 0;
while ((name[i] != '\0') &&
((isdigit(name[i]) != 0) || (name[i] == '-') || (name[i] == '+')))
{
/* do something here */
}
}
remember to include ctype.h and stdio.h
Use isdigit();
Prototype is:
int isdigit(int c);
Similarly to check the character is alphabet
Use
isalpha()
Once you get the string from the user, loop on it to search for correct input. (i.e. to see if there is a digit embedded in a collection of alpha characters). Something like this will work:
Assume userInput is your string:
int i, IsADigit=0;
int len = strlen(userInput);
for(i=0;i<len;i++)
{
IsADigit |= isdigit(userInput[i]);
}
The expression in the loop uses |=, which will detect and keep a TRUE value if any of the characters in the string are a digit.
There are many other methods that will work.
And the following family of character tests will allow you to do similar searches for other types of searches etc.:
isalnum(.) //alphanumeric test
isalpha(.) //alphabetic test
iscntrl(.) //control char test
isalnum(.) //decimal digit char test
isxdigit(.) //hex digit char test
islower(.) //lowercase char test
...The list goes on
I'm new to this forum and would like to seek help. I'm trying to modify an anagram program based on code from http://www.sanfoundry.com/c-program-...ings-anagrams/.
This time, however, I have used array pointers to obtain input from the user. I have also created a function "check_input" to ensure that the input consists of ONLY characters and excludes symbols(!, #, $). However, when I ran the program, it still accepts those symbols and does not break like I wanted it to. Please help.
Plus, I intend to make the program treat upper-case letters the same way as lower-case letters. Can this be achieved by using the "stricmp" function? If so, where should I place that function? Alternative methods are also appreciated.
Update: Sorry. I've added the check_input code at the bottom.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int test_anagram(char *ptrArray1, char *ptrArray2);
int check_input(char array1[], char array2[]);
int main()
{
char array1[100], array2[100];
char *pArray1, *pArray2;
int flag;
pArray1 = array1;
pArray2 = array2;
printf("Enter the first word: \n");
gets(pArray1);
printf("Enter the second word: \n");
gets(pArray2);
check_input(pArray1, pArray2);
flag = test_anagram(pArray1, pArray2);
if(flag == 1){
printf("\"%s\" and \"%s\" are anagrams.\n", pArray1, pArray2);
}else{
printf("\"%s\" and \"%s\" are not anagrams.\n", pArray1, pArray2);
}
return 0;
}
int test_anagram(char array1[], char array2[])
{
int num1[26] = {0}, num2[26] = {0}, i = 0;
while(array1[i] != '\0')
{
num1[array1[i] - 'a']++;
i++;
}
i = 0;
while(array2[i] != '\0')
{
num2[array2[i] - 'a']++;
i++;
}
for(i=0;i<26;i++)
{
if(num1[i] != num2[i]){
return 0;
}
return 1;
}
}
int check_input(char array1[], char array2[])
{
while(isalpha((int)array1) != 1){
break;
}
while(isalpha((int)array2) != 1){
break;
}
}
You haven't (yet) posted the full code of the check_input() function but one advice would be to validate the input when the user inputs every character.
You can do this using f.e. the getchar() function and checking if the inputted character is a letter, as well as converting it to the lowercase (or uppercase if you will).
You can do lowercase convertion like this:
#include <ctype.h>
// ...
tolower('A');
I have an input string such as :"Hello 12345 WoRlD"
and I want output it as : "hELLO 54321 wOrLd"
1)here the lower case should be converted to upper and vice versa
2)reverse the integers between two strings
after executing it will only prints first string only and the rest of output vanishes
Here is what I have attempted so far
#include<stdio.h>
#include<string.h>
char* casechange(char *);
main()
{
char s[30],*p,*q;
int i,j;
printf("Enter string data:");
scanf("%s",s);
q=casechange(s);
printf("Manipulated string data:%s\n",s);
}
char* casechange(char *s)
{
int i,j=strlen(s)-1,num;
for(i=0;s[i];i++)
{
if(s[i]>='a'&&s[i]<='z')
{
s[i]-=32;
}
else if(s[i]>='A'&&s[i]<='Z')
{
s[i]+=32;
}
}
if(s[i]>='0'&&s[i]<='9'&&s[j]>='0'&&s[j]<='9')
//for(i=0;i<j;i++,j--)
//{
{
num=s[i];
s[i]=s[j];
s[j]=num;
}
//}
return s;
}
How can this be accomplished?
The problem with "after executing it will only prints first string only and the rest of output vanishes" is:
scanf("%s",s);
The scanf() '%s' format string tells scanf to read in a string, but only up to the first space. Hence, if you enter:
"Hello 12345 WoRlD"
The scanf("%s", s) will copy only "Hello" into 's'.
To fix this, change:
scanf("%s",s);
To this:
fgets(s, sizeof(s), stdin);
However, fgets() may leave a unwanted '\n' at the end of the string. The unwanted '\n' can be eliminated by inserting the following code after the fgets():
q=strchr(s,'\n');
if(q)
*q = '\0';
Then the output will be:
"hELLO 12345 wOrLd"
SPOILER ALERT!
See my version 'casechange()', which will also reverse the number.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char* casechange(char *);
int main(){
char s[30];
printf("Enter string data:");
scanf("%29[^\n]",s);//%s : separated by white space
casechange(s);
printf("Manipulated string data:%s\n", s);
return 0;
}
char* casechange(char *s){
int i;
for(i=0;s[i];i++){
if(islower(s[i]))
s[i] = toupper(s[i]);
else if(isupper(s[i]))
s[i] = tolower(s[i]);
else if(isdigit(s[i])){
int j, n;
char num[30];
sscanf(&s[i], "%29[0123456789]%n", num, &n);
for(j=0;j<n;++j)
s[i+j] = num[n-j-1];
i+=n-1;
}
}
return s;
}
else if(isdigit(s[i])){
int j, n;
char num;
sscanf(&s[i], "%*[0123456789]%n", &n);
for(j=0;j<n/2;++j){
num = s[i+j];
s[i+j] = s[i+n-j-1];
s[i+n-j-1] = num;
}
i+=n-1;
}
#include <stdio.h>
#include <string.h>
int main()
{
char s[15];
int i,j,n,*str;
printf("Enter a string");
scanf("%s",str);
n=strlen(str);
for(i=0;i<n;i++)
{
str[n]=str[0];
for(j=0;j<n;j++)
{
str[j]=str[j+1];
}
str[n]='\0';
printf("\n %s",str);
}
return 0;
}
this program gives me all possible rotations of string
can anyone explain str[n]=str[0] and str[j]=str[j+1] meaning
instead of taking n=strlen(s) can we use n=strlen(str)
plz explain
This rotates the string. The way it does so is by moving the first character to the last place by doing str[n] = str[0] (str[n] is the string-terminating null character '\0', then shifting the whole string down one (str[j] = str[j+1]), then replacing the null at the end (str[n]='\0').
This code would, if it were using s, cause a buffer overrun if the string is longer than 14 characters. However, there's also a logic error in the code: it should be either initializing str (as a char* not int*) or scanning into s with a length bound. For instance:
scanf("%14s", s);
or
str = (char*)malloc(500);
scanf("%500s", str);
instead of taking n=strlen(s) can we use n=strlen(str)
Actually, since str is an int-pointer that is not initialized anywhere, all uses of str should be replaced by s (it's probably just a typo).
#include <stdio.h>
#include <string.h>
int main()
{
char s[15];
char tmp_var;
int i,j,n,*str;
printf("Enter a string");
scanf("%s",str);
n=strlen(str);
for(i=0;i<n/2;i++)
{
tmp_var = str[i];
str[i] = str[n-i];
str[n-i] = tmp_var;
}
printf("\n Rotated String is %s \n",str);
return 0;
}