Findinga number in char - c

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

Related

Do-while or while loop that will keep taking an input from user but will terminate after I input the string "exit" (case insensitive) in c language

#include <stdio.h>
#include <ctype.h>
int main() {
char str[100];
char out[] = "exit";
do {
printf("Enter a string: ");
scanf("%s", str);
// some if else statement here
} while (toupper(str[3]) != toupper(out[3]));
}
I put the index 3 because if I put the index 0 there, the code will terminate if the entered string starts with letter e. I tried the while loop but it does not work for me. Also I want to print a prompt message that says "detected terminate keyword" after entering the word "exit" and then terminates the loop.
You will also notice the toupper() function. I used it there because I want my loop to be case insensitive, so regarless of lowercase or uppercase or combination of both, the loop should terminate when the word "exit" is entered.
toupper(str[3]) != toupper(out[3]) will compare the upper case 4th letter of str and out, so the loop will iterate till str[3] is 'T'. You want to use strcasecmp(str, out) instead. Remember to #include <strings.h>.
There are multiple problems:
it is confusing for a function isPalindrome() to return 0 for true.
to avoid undefined behavior on negative char values, a char argument to toupper should be cast as (unsigned char).
the test for the exit keyword is incorrect. You exit if the fourth letter is a t or a T. You should use strcasecmp to test for the exit word.
scanf("%s", str) has potential undefined behavior if the user enters a word with more than 99 bytes. Use scanf("%99s", str) and test the return value: it must be 1 for a successful conversion.
instead of a confusing do / while loop, use a for (;;) loop (also known as for ever loop), and test for 2 exit conditions: scanf() failure to read a word and reading the word exit.
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int isPalindrome(const char *str) {
size_t len = strlen(str);
for (size_t i = 0; i < len; i++) {
if (toupper((unsigned char)str[i]) != toupper((unsigned char)str[len - i - 1]))
return 0;
}
return 1;
}
int main() {
char str[100];
for (;;) {
printf("Enter a string: ");
if (scanf("%99s", str) != 1)
break;
if (!strcasecmp(str, "exit"))
break;
if (isPalindrome(str)) {
printf("%s is a palindrome!\n\n", str);
} else {
printf("%s is not a palindrome!\n\n", str);
}
}
return 0;
}
I put the index 3 because if I put the index 0 there, the code will terminate if the entered string starts with letter e
Exactly, and the code:
while (toupper(str[3]) != toupper(out[3])
Suffers from the same problem, any input with a t as its 4th character index 3 will match and the loop will end, you are comparing a specific character of the string, not the string itself. You can use strcasecmp to assess if the input is indeed exit and ignore casing.
Furthermore using %s specifier is not good, you run the risk of overrunning the destination buffer. You should use a width, %99s for a 100 characters buffer to leave space for the nul byte, if possible consider using fgets instead.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main() {
char str[100];
char out[] = "exit";
do {
printf("Enter a string: ");
scanf(" %99s", str); // space before specifier to clean leading whitespaces
// some if else statement here
} while (strcasecmp(str, out) != 0);
puts("Detected terminate keyword. Goodbye!");
}
char *removeLastChar(char *str, char ch)
{
size_t len;
if(str)
{
len = strlen(str);
if(str[len - 1] == ch) str[len -1] = 0;
}
return str;
}
char *strlwr(char *str)
{
char *wrk = str;
if(str)
{
while(*wrk)
{
*wrk = tolower((unsigned char)*wrk);
wrk++;
}
}
return str;
}
int main(void)
{
char str[100];
const char *out = "exit";
int x = 0;
do
{
printf("Enter a string: ");
if(!fgets(str, sizeof(str), stdin)) break;
removeLastChar(str, '\n');
printf("You entered: \"%s\"\n:", str);
} while (strcmp(strlwr(str), out));
}

is it possible to use fgets to store the userinput from a single line into 2 arrays?

I'm trying to store the user input name into the structure. I am using fgets instead of scanf because I want to control the length of the user input. Is it possible to use fgets to store the user input from a single line separated by white space into 2 arrays (for my case it's the lastName[10] and firstName[10])?
Is the only way to use printf function in order to print 2 strings that are taken from the user by firstName and lastName individually?
#include <stdio.h>
#include <string.h>
struct names {
char lastName[10];
char firstName[10];
} names;
int main() {
printf("Enter names (firstName lastName): \n");
fgets(names.firstName, 10, stdin);
fgets(names.lastName, 10, stdin);
printf("first Name: %s last Name: %s \n", names.firstName, names.lastName);
return 0;
}
The problem with the standard C functions in stdio.h is that they are easy to get wrong which may lead to buffer overflow. Here is a safe way to read the names using a custom function:
#include <ctype.h>
#include <stdio.h>
#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
struct names {
char lastName[10];
char firstName[10];
} names;
void ReadName(char name[], int nameLen)
{
int ch, i;
/*skip whitespace*/
do {
ch = getchar();
} while (isspace(ch));
i = 0;
while ((isgraph(ch) || ((unsigned char) ch >= 128)) && (i < nameLen - 1)) { /*accept any UTF-8 byte*/
name[i] = ch;
i++;
ch = getchar();
}
name[i] = '\0';
}
int main(void)
{
printf("Enter names (first name last name): \n");
ReadName(names.firstName, LEN(names.firstName));
ReadName(names.lastName, LEN(names.lastName));
printf("First name: %s\nLast name: %s\n", names.firstName, names.lastName);
return 0;
}
Edit: Made ReadName accept UTF-8 characters.
You can declare a character array as for example
char line[20];
(the size of the array can be greater than 20) and read data in this character array
fgets( line, sizeof( line ), stdin );
when you can use the function sscanf to read lastName and firstName like
sscanf( line, "%s %s", names.firstName, names.lastName );
Also by determining the position of a blank in line you can determine that each substring is not greater than 9 characters.
Actually, what you are trying to do (including controlling the length of the user input) is better accomplished using scanf:
scanf("%9s %9s",names.firstName,names.lastName);
The "%9s" limits each string to 9 characters (to avoid overflowing your strings), and the space in the format string scans for whitespace, so you can enter first and last names on a single input line.

Error : Wrong comparison between pointer and integer

My code seems fine, but I get this warning (warning: comparison between pointer and integer), what is the best solution to solve this problem?
I have already used double notation marks for (char exit = "E"), also used the same thing with while but the same problem.
#include <stdio.h>
int main()
{
char c[1];
char exit = 'E';
while (c != exit)
{
printf("Enter a character\n\n");
scanf("%s", c);
printf("your character is : %s\n-------------------\n", c);
}
}
#include <stdio.h>
int main()
{
char c[1];
char exit = 'E';
while (c != exit) // here ...
{
printf("Enter a character\n\n");
scanf("%s", c);
printf("your character is : %s\n-------------------\n", c);
}
}
you are trying to compare a char to the pointer the array c decays to. What you perhaps wanted to do is to compare the first character of the array to the character exit:
while (c[0] != exit)
But that still doesn't make much sense since c is uninitialized and the user not yet had a chance to make any input. Better use a do ... while-loop:
#include <stdio.h>
int main()
{
char c[1];
char exit = 'E';
do {
printf("Enter a character\n\n");
scanf("%s", c);
printf("your character is : %s\n-------------------\n", c);
} while (c[0] != exit);
}
Next thing is, that scanf("%s", c); could fail (yes unlikely, but possible). And the user could enter more characters than there is room for in the array c. You should never use scanf() whithout checking the return value nor "%s" without specifying a WIDTH for the conversion specifier to limit the characters put into the array.
When reading a string you need memory for WIDTH characters + a terminating '\0'. So if you want to read a string of one character, the array has to have at least 2 elements:
#include <stdlib.h
#include <stdio.h>
int main()
{
char c[2];
char exit = 'E';
do {
printf("Enter a character\n\n");
while (scanf("%1s", c) != 1 ) {
fputs("Input error!\n");
return EXIT_FAILURE;
}
printf("your character is : %s\n-------------------\n", c);
} while (c[0] != exit);
}
But if you only want to read one character you are better off with getchar():
#include <stdio.h>
{
int ch;
while (printf("Enter a character\n\n"),
(ch = getchar()) != EOF && ch != 'E')
{
printf("your character is: %c\n-------------------\n", (char) ch);
}
}
i believe this is what you are trying to do.
warning is because you have not initialzed your character and also you were comparing address of character to character value.
#include <stdio.h>
int main()
{
char c[1];
char exit = 'E';
while ((c[0]=getchar()) != exit)
{
if(c[0]==EOF)break;
printf("your character is : %c\n",c[0]) ;
}
printf("ended");
}

Anagram problems

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');

Running isdigit() on a scanfed Character in C

I am refreshing my C skills and am having a little bit of difficulty with a simple program I am working on. Here it is:
#include <stdio.h>
#include <ctype.h> // for isdigit()
#include <stdlib.h> // for atoi()
int main (int argc, const char * argv[])
{
// first read in # of file events to follow, if not an int,
// complain & abort
char *input;
input = malloc(2); // input[0] holds the character
// input[1] holds the terminator
int numLines = 0;
scanf("%c", &input);
if (isdigit((int)input)) {
numLines = atoi(input);
} else {
printf("First line of input must be int type! Aborting...\n");
return 1;
}
//...
}
The problem is, then even when I enter a number (i.e. 2) it still outputs the aborting message and exits:
2
First line of input must be int type! Aborting...
I am having a hard time figuring out why it behaves like it is and what I should do to fix the problem. Shouldn't the '%c' specifier tell the compiler to take in the input as an ANSI character and then isdigit() should properly interpret that to be an integer?
Thanks in advance!
Change this:
scanf("%c", &input);
if (isdigit((int)input)) {
to this:
scanf("%c", input);
if (isdigit(input[0])) {
As it is right now, you are overwriting the pointer itself, rather writing to the allocated memory.
Also, you need to null-terminate:
input[1] = '\0';
Furthermore, it's not necessary to allocate memory for this. You can get away with just:
char input[] = " ";
scanf("%c", input);
if (isdigit(input[0])) {
numLines = atoi(input);
or alternatively:
char input;
scanf("%c", &input);
if (isdigit(input)) {
numLines = input - '0';
Change your code to:
char input[2] = {0}; // <<-- you don't clear the memory after malloc,
// your atoi might fail. No need for malloc here.
int numLines = 0;
scanf("%c", &input[0]);
if (isdigit((int)input[0])) {
numLines = atoi(input);
} else {
printf("First line of input must be int type! Aborting...\n");
return 1;
}
And you're good. No need to dynamically allocate here, its just a waste of effort.
When you pass &input to scanf, you are passing a pointer to a char *. You should just pass the pointer itself, that is,
scanf("%c", input);

Resources