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');
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;
}
printf("Enter number of patients:");
int numberOfInputs = scanf("%d", &patients);
if (numberOfInputs != 1) {
printf("ERROR: Wrong number of arguments. Please enter one argument d.\n");
}
I am asking the user to input one number as an argument, but would like to print out a statement if the user does not input anything or puts in more than one input. For example, once prompted with "Enter number of patients:", if the user hits enter without entering anything, I would like to print out a statement. The code above is what I have been specifically tinkering around with it for the past couple hours as a few previous posts on this site have suggested but when I run it in terminal, it does not work. Any suggestions? Thank you in advance, and all advice is greatly appreciated!
If I understand your question right, you want to print an error when the input is anything other than an integer and this includes newline as well. You can do that using a char array and the %[] specifier.
Example:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int patients;
char str[10];
printf("Enter number of patients:");
int numberOfInputs = scanf("%[0-9]", str);
if (numberOfInputs != 1) {
printf("ERROR: Wrong number of arguments. Please enter one argument.\n");
}
patients = atoi(str); //This is needed to convert the `str` back to an integer
}
This will print the error when the user just hits ENTER as well.
This looks super over-complicated, but it basically splits the input, checks it to be exactly one and than checks it to be an integer (and converts it). It works fine in loop as well and handles empty input.
I'm sure there are more elegant solutions to this problem, it's just a suggestion.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
int getNumberOfInput(char* str);
bool isNumber(char* str);
int main()
{
char str[512];
while(1)
{
printf("Enter text: ");
fgets(str, 512, stdin);
int numberOfInput = getNumberOfInput(str);
if ( numberOfInput == 0 )
printf("You must give an input\n");
else if ( numberOfInput > 1 )
printf("You have to give exactly one input\n");
else
{
if (!isNumber(str))
printf("The input is not an integer\n");
else
{
int input = atoi(str);
printf("input: %d\n", input);
}
}
}
return 0;
}
int getNumberOfInput(char* str)
{
char* word = strtok(str, " \t\n\v\f\r");
int counter = 0;
while(word != NULL)
{
++counter;
word = strtok(NULL, " \t\n\v\f\r");
}
return counter;
}
bool isNumber(char* str)
{
int i, len = strlen(str);
for (i=0; i<len; ++i)
if (!isdigit(str[i]))
return false;
return true;
}
I currently have a homework assignment and I used gets.
The professor said I should be using getchar instead.
What is the difference?
How would I change my code to use getchar? I can't seem to get it right.
code:
#include <stdio.h>
#include <string.h>
#include <strings.h>
#define STORAGE 255
int main() {
int c;
char s[STORAGE];
for(;;) {
(void) printf("n=%d, s=[%s]\n", c = getword(s), s);
if (c == -1) break;
}
}
int getword(char *w) {
char str[255];
int i = 0;
int charCount = 0;
printf("enter your sentence:\n"); //user input
gets(str);
for(i = 0; str[i] != '\0' && str[i] !=EOF; i++){
if(str[i] != ' '){
charCount++;
} else {
str[i] = '\0'; //Terminate str
i = -1; //idk what this is even doing?
break; //Break out of the for-loop
}
}
printf("your string: '%s' contains %d of letters\n", str, charCount); //output
strcpy(w, str);
// return charCount;
return strlen(w); //not sure what i should be returning.... they both work
}
gets() was supposed to get a string from the input and store it into the supplied argument. However, due to lack of preliminary validation on the input length, it is vulnerable to buffer overflow.
A better choice is fgets().
However, coming to the usage of getchar() part, it reads one char at a time. So basically, you have to keep reading from the standard input one by one, using a loop, until you reach a newline (or EOF) which marks the end of expected input.
As you read a character (with optional validation), you can keep on storing them in str so that, when the input loop ends, you have the input string ready in str.
Don't forget to null terminate str, just in case.
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
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int compare(char word[], char mystery[])
{
int i=0;int bool=1;
while((i<=20)&&(bool==1))
{
if (word[i]==mystery[i])
i++;
else
bool=0;
}
return bool;
}
char readCharacter()
{
char character = 0;
character = getchar();
character = toupper(character);
while (getchar() != '\n') ;
return character;
}
void readString(char *word,char *mystery)
{
int i=0;
printf("Enter the word to guess : ");
scanf("%s",word);
while(*((word)+(i)) != '\0')
{
*((word)+(i))= toupper(*(word+i));
*((mystery)+(i))='*';
i++;
}
*(mystery+i)='\0';
}
void process(char *word,char *mystery,char letter,int *change)
{
int i=0;
while (*((word)+(i))!= '\0')
{
if (*((word)+(i))==letter)
{
*((mystery)+(i))=letter;
*change=1;
}
i++;
}
}
void test(char *word,char *mystery, int triesleft)
{
if (*mystery!=*word)
{
printf("The mystery word is : %s",*mystery);
printf("\n You have %d tries left.", triesleft);
}
else
{
printf("You won !");
}
}
int main()
{
int triesleft = 10; int change=0;
char word[20]; char mystery[20];char letter;
readString(&word,&mystery);
while((compare(word,mystery)==0) && (triesleft>0))
{
change=0;
printf("Enter the letter :");
letter=readCharacter();
process(&word,&mystery,letter,&change);
if ((change)==1)
triesleft--;
test(&word,&mystery,triesleft);
}
if (triesleft>0)
return 0;
printf("You lost.");
return 1;
}
I'm a beginner in C and I wanted to code a simple Hangman game in C and it compiled fine but it seems to crash after entering the first letter and I can't find a solution !
I don't know what may be the cause but I had a lot of trouble using strings in C, as they don't exist maybe it was a bad manipulation of that I don't know :/
You first call to readString is enough to crash the program.
word and mystery are arrays, so &word is a char ** not a char *. You should use
readString(word, mystery);
But compiler should have issue a warning on that. Warning are not there to distract beginners to to denote possible (probable if you do not understand the warning) mistakes.
There are probably other problems later ...
In the readString() function, you should use '\0' instead of NULL, as C strings are ended with this character.
You cannot declare a variable named bool as it is a type. In C, it is not actually defined for all compilers as bool is not part of the standard but some compilers and some platform will define it anyway