scanf("%c%c%c%c", &var1, &var2, &var3, &var4);
if ((var1 != 'f' || '+' || '-' || '[' || ']') ||
(var2 != 'f' || '+' || '-' || '[' || ']') ||
(var3 != 'f' || '+' || '-' || '[' || ']') ||
(var4 != 'f' || '+' || '-' || '[' || ']'))
printf("Invaild input\n");
this is my code,i want user to enter 4 variables with space between each one and the output to be invaild if the input is diffrent from any of this chars.right now no matter what i enter into the code the "invalid input" is the output. is there something wrong in here?
The main reason why it does not work is because your conditions like (var1 != 'f' || '+' || '-' || '[' || ']') do something completely different than you might think. An expression like (anyBooleanValue || '+') will always return true, regardless what the value of anyBooleanValue is. This is because the RHS operand '+' is a character literal, i.e. an integral value representing (very likely) the ASCII-code of character '+'. Any integral value other than 0 is treated as true, so it reads like anyBooleanValue || true, which obviously is always true.
So you actually would have to write something like if (var1 != 'f' && var1 != '+' && ... as #WhozCraig mentioned.
But actually you have the same code appearing again and again, and such cases are usually handled by loops. And the test of whether a character appears in a set of possible characters can be solved easily with function strchr, which returns a pointer to the first occurrence of the character in question or NULL, if the character does not occur. The following code illustrates this:
int main() {
#define nvars 4
char vars[nvars];
int i;
for (i=0; i<4; i++) {
scanf(" %c", &vars[i]);
if (strchr("f+-[]",vars[i]) == NULL) { // char not found?
break;
}
}
if (i<4) {
printf("Invaild input\n");
} else {
printf("valid.\n");
}
}
Note further the leading blank in scanf(" %c", which is for consuming white spaces before the actual character.
#Stephan Lechner well identified the problems with OP's code and a good solution. Below is an alternative solution to check if a character is one of several characters in one step. Use a look-up table.
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>
int mango_test(unsigned char ch) {
// If char is not too big
#if UCHAR_MAX < 1024
static const bool good[UCHAR_MAX + 1] = { //
['f'] = 1, ['+'] = 1, ['-'] = 1, ['['] = 1, [']'] = 1}; // look-up table
return good[ch];
#else
char *s = strchr("f+-[]", ch);
return s && ch; // Found in list and not the null character.
#endif
}
int main(void) {
for (int ch = SCHAR_MIN; ch <= UCHAR_MAX; ch++) {
int found = mango_test(ch);
if (found)
printf("Found %d <%c>\n", ch, ch);
}
}
Output
Found 43 <+>
Found 45 <->
Found 91 <[>
Found 93 <]>
Found 102 <f>
Related
So, my code actually works perfectly when I use function that checks for special characters in string by explicitly giving symbols:
int isSpecialCharacter(char str[], int n)
{
for(int i=0; i<n;i++)
{
if (str[i] == '!' || str[i] == '#' || str[i] == '#' || str[i] == '$' || str[i] == '%' || str[i] == '^' || str[i] == '(' || str[i] == ')')
{
return 1;
}
return 0;
}
}
However, in the below code I am not able to get my code to find special characters in string using ASCII values. I want to understand what am I doing wrong. In the below code, I have my main() also included that prompts the user to input string.
#include <stdio.h>
#include <string.h>
char str[30][30];
char test[100];
int myindex = 0;
int isSpecialCharacter(char str[], int n)
{
for(int i=0; i<n;i++)
{
if (str[i] == 33 || str[i] == 35 || str[i] == 36 || str[i] == 37 || str[i] == 40 || str[i] == 41 || str[i] == 64)
{
return 1;
}
return 0;
}
}
int main()
{
printf("Please enter 10 strings below: \n");
while(myindex < 10)
{
printf("Enter string %d: ", myindex+1);
fgets(str[myindex], 500, stdin);
strcpy(test, str[myindex]);
int t_size = strlen(test);
if (strlen(str[myindex])<2||strlen(str[myindex])>26)
{
printf("Enter string that is between 2 and 25");
continue;
}
else if(isSpecialCharacter(test, t_size) == 1)
{
printf("Your string has some special characters. \n");
continue;
}
else
{
myindex++;
}
}
return 0;
}
EDIT:
I have included the variable declarations and replaced the code where I use symbols to check for special characters. Thank you.
EDIT2:
These are the characters that I want to look for: : ’!’, ’#’, ’#’, ’$’, ‘%’, ‘^’, ’(’, or ’)’. Not spaces.
Both your functions won't work as you've written them.
The main problem is that the for loop returns after each loop cycle, so you never check beyond the first cycle.
You should move the return 0 statement to the end of the function, then it will work as expected.
int isSpecialCharacter(char str[], int n)
{
for (int i = 0; i < n; i++)
{
if (str[i] == 33 || str[i] == 35 || str[i] == 36 || str[i] == 37 || str[i] == 40 || str[i] == 41 || str[i] == 64)
{
return 1;
}
}
return 0;
}
Test
I've tested the solution with the following input:
test1
test2
test)
test(
test3
test4
test5
test#
test6
test7
test!
test8
test9
test10
And it works. You can see the result there: https://godbolt.org/z/67Px14z75
As suggested from other users in the comment section, using decimal values to refer to characters is a bad practice™ and you should stick with the '#' notation.
Your return 0; is incorrect:
int isSpecialCharacter(char str[], int n) {
for(int i=0; i<n;i++)
{
if (str[i] == '!' || str[i] == '#' || str[i] == '#' || str[i] == '$' || str[i] == '%' || str[i] == '^' || str[i] == '(' || str[i] == ')')
{
return 1;
}
return 0;
}
}
On the very first loop, your function returns either 1 or 0. You only want to return 0 (false) if the loop completes without finding the character you're looking for.
int isSpecialCharacter(char str[], int n)
{
for(int i=0; i<n;i++)
{
if (str[i] == '!' || str[i] == '#' || str[i] == '#' || str[i] == '$' || str[i] == '%' || str[i] == '^' || str[i] == '(' || str[i] == ')')
{
return 1;
}
}
return 0;
}
I'm not going to try to write your code...
if( isSpecialCharacter()
is equivalent to:
if( strpbrk( test, "abqmz" ) != NULL )
(except that the latter has been proven to work...)
If a, b, q, m, z appear in the string, then the if condition is true...
Learn the standard library instead of spending time badly reinventing it...
EDIT:
Here is how an experienced programmer might write that functionality now that you've decoded the decimal ASCII values. (Don't expect the next programmer who reads your code to reach for their ASCII table...)
char spcl[] = "!##$%^()";
if( strpbrk( test, spcl ) != NULL ) {
// Do something because condition is true
NB: if you need to make either \ or " special inside a string, you must 'escape' either of those characters with an 'extra' backslash. Eg:
char spcl[] = "\\!##$%^(\")"; // notice '\\' and '\""
If that looks too much like "bad language", you can construct your own string (ENSURING(!) that it is null terminated.)
char spcl[] = { '\\', '!', '#', '#', '$', '%', '^', '(', '\"', ')' '\0' };
And...
char str[30][30];
/* Skipping ahead */
printf("Enter string %d: ", myindex+1);
fgets(str[myindex], 500, stdin); // 500!!! ????
is simply looking for trouble...
The position of "return 0" is not correct.
It should come after the end of "for loop"
Q : Write a program to count the number of occurrences of any two vowels in succession in a line of text. For example the following sentence :
"Please read the application and give me gratuity"
Such occurrences in the sentence are :- "ea" , "ea" , "io" , "ui". Ultimately the question is to count the number of such occerrences in the line which is a user input string.
Problem : My program is just recieve a line but did not give any output.
It's my first question in stackoverflow. I am a beginner in programming.
My code:
# include <stdio.h>
int main () {
char line[100];
printf("\nEnter a line\n");
gets(line);
//printf("You entered : %s\n", line);
char A,E,I,O,U,a,e,J,o,u;
A = 'A';
E = 'E';
I = 'I';
O = 'O';
U = 'U';
a = 'a';
e = 'e';
J = 'i';
o = 'o';
u = 'u';
int occurence =0,i =0 ;
while (line[i] =! '\0'){
if((line[i] == A || E || I || O || U || a || e || J || o || u) && (line[i+1] == a || e || J || o || u)){
occurence++;
}
i++;
}
printf("Number of occurence of any two vowels in succession in the line is : %d\n", occurence);
return 0;
}
Your code has multiple issues, some of which are:
You use gets to read the string. This function is now at least deprecated (I think it was even removed from recent versions of the standard library) because it is unsafe. Use fgets instead!
You use the || operator wrong - this was already pointed out in mediocrevegetable1's comment.
You could use a code similar to this one to solve your problem. The code contains comments, so it should be easy to understand. However, if this is a homework or project for school, do NOT use this exact code, as this would most likely be considered plagiarism!
#include <stdio.h>
#include <ctype.h>
#define STRLEN 100
int main () {
char line[STRLEN];
char* ch;
char incrementIfVowel;
int occurences;
/* Read line */
printf("\nEnter a line\n");
fgets(line, STRLEN, stdin);
/* Init variables */
incrementIfVowel = 0;
occurences = 0;
/* Iterate through characters */
for (ch = line; *ch != '\0'; ch++) {
/* Test if the current character is a vowel. Three cases can occur: */
if (toupper(*ch) == 'A' || toupper(*ch) == 'E' || toupper(*ch) == 'I' || toupper(*ch) == 'O' || toupper(*ch) == 'U') {
if (incrementIfVowel == 1) {
/* Case 1: The current character is a vowel, and its predecessor was also a vowel */
incrementIfVowel = 0;
occurences++;
}
else {
/* Case 2: The current character is a vowel, but its predecessor was not a vowel or it was the second vowel in a row */
incrementIfVowel = 1;
}
}
else {
/* Case 3: The current character is not a vowel */
incrementIfVowel = 0;
}
}
/* Print result */
printf("Number of occurence of any two vowels in succession in the line is : %d\n", occurences);
return 0;
}
There are 3 main issues with your code:
gets(line);
gets doesn't check the length of the buffer and for this reason, is susceptible to buffer overflows. gets had been deprecated since C99 and was removed in C11. You're probably compiling with an older version of the standard; I'd suggest you switch to newer versions. As for an alternative, see fgets.
while (line[i] =! '\0'){
=! is a typo. Replace it with !=
if((line[i] == A || E || I || O || U || a || e || J || o || u) && (line[i+1] == a || e || J || o || u))
This will always evaluate to true because || doesn't chain like that. Ideally, you should put this in a function:
_Bool is_vowel(char ch)
{
return toupper(ch) == 'A' || toupper(ch) == 'E' || toupper(ch) == 'I' || toupper(ch) == 'O' || toupper(ch) == 'U';
}
toupper is defined in <ctype.h> so be sure to include that. You could also shorten this behemoth of a line with return strchr("AEIOUaeiou", ch), but if you haven't used strchr and are not comfortable with using it yet, that's okay.
Modifying only the incorrect parts, your final code will can look something like this:
#include <stdio.h>
#include <ctype.h>
_Bool is_vowel(char ch)
{
return toupper(ch) == 'A' || toupper(ch) == 'E' || toupper(ch) == 'I' || toupper(ch) == 'O' || toupper(ch) == 'U';
}
int main () {
char line[100];
printf("\nEnter a line\n");
fgets(line, sizeof line, stdin);
int occurence = 0, i = 0;
while (line[i] != '\0') {
if(is_vowel(line[i]) && is_vowel(line[i + 1]))
occurence++;
i++;
}
printf("Number of occurence of any two vowels in succession in the line is : %d\n", occurence);
return 0;
}
An example of running this:
Enter a line
Please do something about the bee hive and then eat some meat
Number of occurence of any two vowels in succession in the line is : 5
(5 because Pl<ea>se do something ab<ou>t the b<ee> hive and then <ea>t some m<ea>t)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am creating a program that requires the user to create a password that has at least one symbol, one uppercase letter, one lowercase letter, and a digit. However, I got so many errors. I fixed most of them but there are still a few I can't seem to figure out. It would be easier to just send a screenshot.
And here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> //To use isupper, isalpha, and isdigit
int main() {
//Declaring the variables
char userPassword;
int i;
int digit = 0;
int upper = 0;
int lower = 0;
int letter = 0;
int symbol = 0;
//User enters password
printf("Please create a password including at least 1 number, 1 uppercase letter, and one symbol: ");
scanf(" %c", &userPassword);
//strlen makes sure password is not less than 8 characters
if (strlen(userPassword) < 8) {
printf("INVALID PASSWORD.");
}
else {
//A for loop that checks if all the conditions are met
for (i = 0; i = 20; i++) {
//Makes sure password has a letter
if (isalpha(userPassword[i])) {
letter++;
}
//Makes sure password has an uppercase letter
else if (isupper(userPassword)) {
upper++;
}
//Makes sure password has a lowercase letter
else if (islower(userPassword)) {
lower++;
}
//Makes sure password has a digit
else if (isdigit(userPassword)) {
digit++;
}
//Makes sure password has a symbol
else if (userPassword == '!' || userPassword == '#' || userPassword == '#' || userPassword == '$' || userPassword == '%' || userPassword == '^' || userPassword == '&' || userPassword == '*' || userPassword == '(' || userPassword == ')' || userPassword == '-' || userPassword == '+' || userPassword == '_');
symbol++;
}
}
//If the password has all of them, it can be created
if (digit == 0 && upper == 0 && lower == 0 && letter == 0 && symbol == 0) {
printf("PASSWORD CREATED.");
}
else {
printf("INVALID PASSWORD.");
}
return 0;
}
Any help would be appreciated!
First of all, we need to address some error in syntax as well as logic. The following things are changed:
userPassword should be a character array. I assume you have chosen maximum length of password as 20 by looking at your for loop. Therefore, declare it as char userPassword[20].
The condition in the for loop is changed to for (i = 0; i < 20; i++).
There was a logical mistake in the algorithm to check the type of the character. Therefore, I have replaced the else if constructs to if.
Character array in C, should be scanned using the %s format specifier.
Also, don't forget to include string.h for the strlen() function.
Have a look a the corrected code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> //To use isupper, isalpha, and isdigit
#include <string.h>
int main() {
//Declaring the variables
char userPassword[20]; //Assuming maximum length of password is 20.
int i;
int digit = 0;
int upper = 0;
int lower = 0;
int letter = 0;
int symbol = 0;
//User enters password
printf("Please create a password including at least 1 number, 1 uppercase letter, and one symbol: ");
scanf(" %s", userPassword);
//strlen makes sure password is not less than 8 characters
if (strlen(userPassword) < 8) {
printf("INVALID PASSWORD.");
}
else {
//A for loop that checks if all the conditions are met
for (i = 0; i < 20; i++) {
//Makes sure password has a letter
if (isalpha(userPassword[i])) {
letter++;
}
//Makes sure password has an uppercase letter
if (isupper(userPassword[i])) {
upper++;
}
//Makes sure password has a lowercase letter
if (islower(userPassword[i])) {
lower++;
}
//Makes sure password has a digit
if (isdigit(userPassword[i])) {
digit++;
}
//Makes sure password has a symbol
if (userPassword[i] == '!' || userPassword[i] == '#' || userPassword[i] == '#' || userPassword[i] == '$' || userPassword[i] == '%' || userPassword[i] == '^' || userPassword[i] == '&' || userPassword[i] == '*' || userPassword[i] == '(' || userPassword[i] == ')' || userPassword[i] == '-' || userPassword[i] == '+' || userPassword[i] == '_'){
symbol++;
}
}
//If the password has all of them, it can be created
if (digit > 0 && upper > 0 && lower > 0 && letter > 0 && symbol > 0) {
printf("PASSWORD CREATED.");
}
else {
printf("INVALID PASSWORD.");
}
}
return 0;
}
Test Cases:
Input 1: Rt%oi45u#
Output: PASSWORD CREATED.
Input 2: Rt%oiu#
Output: INVALID PASSWORD.
At a quick glance:
As the warning says, you'll want #include <string.h> to include the definition of strlen.
You declare userPassword as only one character, not as an array of characters (e.g. userPassword[32]) (which can hold a string up to 31 characters in length).
You should use scanf("%s", userPassword) (or preferably fgets with a maximum length) to read strings.
Your for loop condition is wrong; for (i = 0; i < strlen(userPassword); i++) { is likely what you're looking for.
All but the first if(isalpha...) condition are wrong; you're not indexing the password in the rest (userPassword[i] c.f. userPassword)
There's an extraneous ; after the special-character check, so symbol gets incremented every time
The check for whether all of the required character types exist is inverted; it'd create the password when none of the conditions match.
Your code have 3 errors.
You must include string.h for strlen function.
%c can only cover character. replace %c to %s in scanf(" %c", &userPassword);
And declare userPassword as char array. replace char userPassword[32]
Ok i modified my code but cannot get it to break when the user inputs 0. I tried 0, '0', and "0" and neither break the loop.
#include <stdio.h>
#include<conio.h>
int main(){
int word;
int countword = 0;
int countpunct = 0;
do{
printf("\nEnter the String: ");
while ((word = getchar()) != EOF && word != '\n'){
if (word == ' ' || word == '.' || word == '?' || word == '!' || word == '(' || word == ')' || word == '*' || word == '&'){
countword++;
}
if (word == '.' || word == '?' || word == '!' || word == '(' || word == ')' || word == '*' || word == '&'){
countpunct++;
}
}
printf("\nThe number of words is %d.", countword);
printf("\nThe number of punctuation marks is %d.", countpunct);
} while (word!= 0);
}
Your inner loops break when word is either EOF or \n. Since you never modify it when you get to the end of the outer loop, the condition will always be true.
Going back to your pre-edit code, all you really need is to change scanf("%c", word); to scanf("%c", &word);, although you should use a separate char variable for that, since the %c format specifier expected a pointer to char. So your code should look like this:
#include <stdio.h>
#include <stdlib.h>
int main(){
int word;
char cont;
for (;;){
int countword = 0;
int countpunct = 0;
printf("\nEnter the String: ");
while ((word = getchar()) != EOF && word != '\n'){
if (word == ' ' || word == '.' || word == '?' || word == '!' || word == '(' || word == ')' || word == '*' || word == '&'){
countword++;
}
if (word == '.' || word == '?' || word == '!' || word == '(' || word == ')' || word == '*' || word == '&'){
countpunct++;
}
}
printf("\nThe number of words is %d.", countword);
printf("\nThe number of punctuation marks is %d.", countpunct);
printf("\nContinue? Y/N?");
scanf("%c", &cont);
if (cont!= 'y' && cont!= 'Y'){
return 0;
}
}
}
Note also that countword and countpunct are moved inside of the outer loop. That way, they're initialized to 0 for each new set of words.
My program: Something is wrong
#define _CRT_SECURE_NO_WARNINGS
#include <ctype.h>
#include <stdio.h>
//Функция для проверки соответствия символов.
int ifSignsCorrect(char theChar) {
if ((theChar >= 'A' && theChar <= 'Z') || (theChar >= 'a' && theChar <= 'z') || theChar == '.' || theChar == ' ' || theChar == '*') return 1;
return 0;
}
int main() {
char string[256];
int i = 0;
//Заполняем массив
for (i = 0; i < 256; i++) {
scanf("%c\n", &string[i]);
if (string[i] == '*') break;
printf("%с\n", string[i]);
if (ifSignsCorrect(string[i]) != 1) {
printf("You used wrong characer, formating disc C (Just joking)\n");
return;
}
}
}
Three things I want to mention:
First:
You are trying to access invalid pieces of memory with this code:
int i = 0;
while (string[i - 1] != '*') {
In the first iteration you will access string[-1]. You have to solve that first.
Second:
You are defining an array of pointers in this line:
char *string[256];
use an array of characters char string[256]; instead.
Third:
You could just print like this:
printf("You used wrong characer, formating disc C (Just joking)\n");
Unless you want to define variable that will indicate this error_message, that could be cleaner some times, specially is you are going to reuse it.
Hope it helps.
You used an array of pointers instead of array of characters here:
char *string[256];
You are also accessing the array out of bounds here:
while (string[i - 1] != '*') { // here i == -1
Also a if statement after the scanf() like this would be proper:
if( string[i] == '*' )
break ;
EDIT:
Why does the program only print the character ? ?
Because the character c in the line printf("%с\n", string[i]); is actually not an ascii c
Try copying it into a program that only supports ascii. I copied it into notepad++ and set the encoding to ascii and it turned to ? :) . Must be a multilanguage support error as i see you have cyrillic enabled.