what is wrong with this execution of OR operand in C [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
When I separate the str[i] with all the vowels it works, what is wrong with the current execution?
#include <stdio.h>
#include<string.h>
int main() {
int k = 0;
char str[100];
scanf("%[^\n]s", str);
for(int i = 0; i < strlen(str); i++){
if(str[i] == ('a' || 'e' || 'i' || 'o' || 'u')){
k++;
}
}
printf("%d",k);
}

It compares str[i] with the expression 'a' || 'e' || 'i' || 'o' || 'u', which gets evaluated to true, which value is equal to 1. Think about characters as integers, which char correspond to (in ASCII), then your expression would be 97 || 101 || ..., which is certainly true.
To make this work as intended, you need to split all comparisons:
str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u'

When I separate the str[i] with all the vowels it works...
This is due to the fact that you are comparing a character with a boolean expression, which will be either 1 or 0, this comparison will never be true, str will not have any characters with 0 or 1 codes, these are non-printable control characters.
In practical terms ('a'||'e'||'i'||'o'||'u') is equivalent to (97 || 101 || 105 || 111 || 117) these are each character's ASCII codes as an example, other encodings will have different codes, this is how your program really sees them.
Anyway, this sequence of OR's will evaluate to 1, so let's say str[i] is 'a', the comparison will be 97 == 1, this is of course false, the same for the other vowels, so k will never be incremented.
Of course separating the characters one by one will work because each individual comparison will now work as expected.
If you don't like the long if you can use :
#include <stdio.h>
#include <string.h>
int main() {
int k = 0;
char str[100];
scanf("%[^\n]", str);
for (int i = 0; i < strlen(str); i++) {
switch(str[i]){
case 'a': case 'e': case 'i': case 'o': case 'u':
k++;
}
}
printf("%d", k);
}
Or you can use strchr as posted by Vlad.
On a side note, scanf("%[^\n]s", str); should be scanf("%[^\n]", str);, the %[^\n] specifier doesn't need an s at the end, if you include it it means that scanf will be expecting a string ending in s.

According to the C Standard (6.5.14 Logical OR operator)
3 The || operator shall yield 1 if either of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
So this primary expression within the condition of the if statement
('a'||'e'||'i'||'o'||'u')
is always evaluates to integer 1 because at least the first operand 'a' is unequal to 0.
So in fact this if statement
if(str[i]==('a'||'e'||'i'||'o'||'u')){
is equivalent to
if( str[i] == 1 ){
and it evaluates to logical true only in one case when str[i] is equal to 1.
You need to write
if( str[i] == 'a' || str[i] == 'e'|| str[i] == 'i'|| str[i] == 'o'|| str[i] == 'u' ){
Another approach is to use the standard function strchr. For example
if ( strchr( "aeiou", str[i] ) ) {
//...
}

You probably forgot that you should use operators with two operands, so the compiler could recognize each operation and label them as True or False. use this code instead:
int main() {
int k=0;
char str[100];
scanf("%[^\n]s",str);
for(int i=0;i<strlen(str);i++){
if((str[i]== 'a')||(str[i] == 'e')||(str[i] == 'i')||(str[i] == 'o')||(str[i] == 'u')){
k++;
}
}
printf("%d",k);
}```

Related

What is causing the new line character to not work in my program?

I am not sure why my new line is not working for printf(operand1, "%s\n"); I print test afterwards and its not on a new line.
#include <stdio.h>
int main(){
printf("Enter elementary operation:"); //Output to console for user to see
char input[32]; //Create a char array of size 32 characters (32 bytes or 256 bits), can only store 255 due to needing the end string character which is '\0'
fgets(input, sizeof(input), stdin); //get line that user inputs
printf(input,"%s\n"); //print the string the user input
char operand1[32];
int i = 0;
while(input[i] == '0' || input[i] == '.' || input[i] == '1' || input[i] == '2' || input[i] == '3' || input[i] == '4'
|| input[i] == '5' || input[i] == '6' || input[i] == '7' || input[i] == '8' || input[i] == '9' || (i == 0 && input[i] == '-')){
operand1[i] = input[i];
i++;
}
printf(operand1, "%s\n");
printf("test");
return 0;
}
Output is:
Enter elementary operation:99+0
99+0
99test%
First, it should be printf("%s\n",operand1). What happens in your code is that operand1 is treated as format string and since it doesn't have % in it, it is printed as is.
Second, your operand1 doesn't have zero byte after the copied chars, so it's not really a string from C's point of view and when you pass it to printf with %s format option printf will print your memory content until it accidentally hits a 0. Although, perhaps this behavior won't happen, because when you allocate an array it might be pre-initialized with zeros - depends on lots of things. It is more correct and safe to add operand1[i] = '\0' after the loop
Third, there is isdigit function (defined in <ctype.h>), that you can use i/o testing manually for all the digits. Or you can use comparison (input[i] >= '0' && input[i] <= '9')

Find vowels in a string

Given below is my code for finding vowels in a given string:
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
int i, str_length;
//scanf("%[^\n]%*c", &str[100]);
fgets(str, sizeof(str), stdin);
str_length = strlen(str);
for (i = 0; i < str_length; i++) {
if (str[i] == 'a' || str[i] == 'e' ||
str[i] == 'i' || str[i] == 'o' ||
str[i] == 'u' || str[i] == 'A' ||
str[i] == 'E' || str[i] == 'I' ||
str[i] == 'O' || str[i] == 'U')
{
printf("Vowels in the string are: %c \n", str[i]);
}
}
return 0;
}
I just wanna know, why scanf("%[^\n]%*c",&str[100]) is not working in my code?
cause I tried executing my program multiple times using scanf but it didn't worked.
And after using fgets I got the desired output.
So, can anyone help me to understand, where I am wrong!!
In the scanf function call, this &str[100] takes a pointer to str, makes it point to the element with the index 100 (which is past the end of the array), dereferences it and then takes the address of that (non-existing) element. This, most likely, leads to an attempt to an invalid write, which is probably caught by the operating system which terminates your program. In any case, the string is not written to the correct location.
Instead, you want the argument to point to the memory location of the first element of str, i.e.:
scanf("%[^\n]%*c", str);
That said, using fgets is better as it accepts an argument for the size which prevents buffer overflows. A size can also be given to scanf, but since it is part of the format specifier it cannot be a variable; only a hardcoded constant:
scanf("%99[^\n]%*c", str);
Note that this is for 99 elements, as there needs to be room for the null-terminator (\0) as well. See here for more info on scanf. But again, using fgets is less error prone and to be preferred.
Some additional advice:
The typical signature of the main function, using no parameters, is int main(void).
The scanf version fails if the input is a single newline character. Both versions fail on no input. It is always a good idea the check the return values of input (and output) functions.
Inside of the for-loop, you could create a copy of the current character converted to lowercase using the tolower function, and then perform only the lowercase comparisons. I.e.:
for (i = 0; i < str_length; i++) {
char ch = tolower(str[i]);
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u')
printf("Vowels in the string are: %c \n", str[i]);
}
Another option is to replace the comparisons in the if-statement with a call to strchr, which makes the program a bit more generic and scalable (one string is more easily changed than multiple comparisons):
char ch = tolower(str[i]);
if (strchr("aeiou", ch) != NULL)
printf("Vowels in the string are: %c \n", str[i]);

Program to find vowels, If statements not assigning correct values [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I have a simple program to find the vowels in a string. The for loop is supposed to iterate through the string and see if the char matches any of the vowels using and if else block but the output is just 100 As.
I tried making them all just ifs but that gave all Us.
#include <stdio.h>
int main()
{
const int SIZE = 100;
char str[SIZE] = {"the brown fox\0"};
char vowels[SIZE];
for (int i = 0; i <= SIZE; i++) {
if (str[i] == '97' || '65') {
vowels[i] = 'a';
}
else if (str[i] == '101' || '69' ) {
vowels[i] = 'e';
}
else if (str[i] == '105' || '73') {
vowels[i] = 'i';
}
else if (str[i] == '111' || '81') {
vowels[i] = 'o';
}
else if (str[i] == '117' || '85') {
vowels[i] = 'u';
}
printf("%c", vowels[i]);
}
return 0;
}
EDIT: Fixed the assignment if e.g. (str[i] == '97' || str[i] == '65') now it's printing strange symbols
EDIT 2: New code
#include <stdio.h>
int main()
{
const int SIZE = 100;
char str[SIZE] = {"the brown fox\0"};
char vowels[SIZE];
for (int i = 0; i <= SIZE; i++) {
if (str[i] == 'a' || str[i] == 'A') {
vowels[i] = 'a';
}
else if (str[i] == 'e' || str[i] =='E' ) {
vowels[i] = 'e';
}
else if (str[i] == 'i' || str[i] == 'I') {
vowels[i] = 'i';
}
else if (str[i] == 'O' || str[i] == 'o') {
vowels[i] = 'o';
}
else if (str[i] == 'u' || str[i] == 'U') {
vowels[i] = 'u';
}
printf("%c", vowels[i]);
}
return 0;
}
EDIT 3: Even after initialing vowels to '' at the start of the loop as suggested the strange symbols are gone but it's still not functioning properly.
You are comparing your char str[i] with '97'
6.4.4.4
An integer character constant has type int. The value of an integer character constant containing a single character that maps to a single-byte execution character is the numerical value of the representation of the mapped character interpreted as an integer. The value of an integer character constant containing more than one character (e.g., 'ab'), or containing a character or escape sequence that does not map to a single-byte execution character, is implementation-deļ¬ned.
If you want to compare a char you can use the ascii value for example 97 or directly the char with 'c'.
For more maintenability and readability I prefer using the char directly.
There is other problems in your code:
First, in your for loop: for (int i = 0; i <= SIZE; i++) {
You are going too far in your array because of your <= as arrays id starts with 0, if you type str[100], in reality you are using the 101st char.
Another problem is your if statements: if (str[i] == '97' || '65') {
Here your if statement is equivalent to if (str[i] == '97' || '65' != 0) {
Consider retyping str[i] == : if (str[i] == '97' || str[i] == '65') {
Plus don't forget the first problem I mentionned about your '97'
You have a very large number of small problems summarized below:
#define SIZE 100 /* if you need a constant, #define one (or more) */
...
char vowels[SIZE] = ""; /* initialize all zero, {0) is valid also */
An integer constant is created by #define or by use of an enum. A const qualified int is not a constant integer. (that said VLAs are legal in C99, but optional in C11)
int idx = 0; /* separate index for filling vowels array */
Keep a separate index for filling the vowels array.
/* don't use magic-numbers in your code */
if (str[i] == 'a' || str[i] == 'A') {
Don't use magic-numbers, instead, use literal character constants were needed in your code to produce much more readable code.
Your program takes arguments, use them to pass the string to parse (or read from stdin), e.g.
int main (int argc, char **argv) {
const char *str = (argc > 1) ? argv[1] : "the brown fox";
...
The test ? if_true : if_false operator is called the ternary operator. It allows a simple in-line conditional to select one of two values based on the test condition (e.g. (argc > 1))
If you plan on using vowels as a string, don't forget to nul-terminate vowels after the loop, e.g.
vowels[idx] = 0; /* nul-terminate vowels */
Correcting all the errors and adding the arguments to main() you could do something similar to:
#include <stdio.h>
#define SIZE 100 /* if you need a constant, #define one (or more) */
int main (int argc, char **argv) {
const char *str = (argc > 1) ? argv[1] : "the brown fox";
char vowels[SIZE] = ""; /* initialize all zero, {0) is valid also */
size_t idx = 0; /* separate index for filling vowels array */
for (int i = 0; idx < SIZE - 1 && str[i]; i++) {
/* don't use magic-numbers in your code */
if (str[i] == 'a' || str[i] == 'A') {
vowels[idx++] = 'a'; /* assign 'a', increment index */
}
else if (str[i] == 'e' || str[i] == 'E' ) {
vowels[idx++] = 'e';
}
else if (str[i] == 'i' || str[i] == 'I') {
vowels[idx++] = 'i';
}
else if (str[i] == 'o' || str[i] == 'O') {
vowels[idx++] = 'o';
}
else if (str[i] == 'u' || str[i] == 'U') {
vowels[idx++] = 'u';
}
}
vowels[idx] = 0; /* nul-terminate vowels */
printf (" %zu vowels: ", idx); /* print number of vowels */
for (int i = 0; vowels[i]; i++) /* output each vowel, comma-separated */
printf (i > 0 ? ", %c" : "%c", vowels[i]);
putchar ('\n'); /* tidy up with newline */
return 0;
}
Example Use/Output
bin\vowels.exe "a quick brown fox jumps over the lazy dog"
11 vowels: a, u, i, o, o, u, o, e, e, a, o
Depending on your compiler str[i] == '117' (and the rest) may give you an error as signle quotes are only to be used when you want to implement the ascii equivalent of a single character like 'a' or so. Therefore str[i] == '117' is checking if str[i] is equal to the ascii equivalent of "117".
Other than that " || " is a logical "or" operator. When you write down str[i] == '111' || '81' you simply mean "find ascii codes of 111 and 81(which dont exist) , use them in "or" operation, check if the result equals str[i]".
last but not least i found a nice function online which might help making your code more compact
int isvowel(int ch)
{
int c = toupper(ch);
return (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U');
}
to explain it shortly, if the char equivalent of given int ch is lowercase, the function changes it to uppercase and checks if it is an uppercase vowel, if the given integer already equals an uppercase vowel int c = toupper(ch); doesnt change anything.
Implementation can be done as:
for(int i=0; i<SIZE; i++) //scan all emelents of str[SIZE]
{
if(isvowel(str[i])) //print if vowel
printf ("%c", str[i]);
}

Finding points of a scrabble word [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So i recently started c language with no prior knowledge of coding or computer science. Wrote this piece of code to find value of a word using scrabble points as below:
1:AEILNORSTU 2:DG 3:BCMP 4:FHVWY 5:K 8:JX 10:QZ.
# include <stdio.h>
# include <ctype.h>
# include <conio.h>
int main (void)
{
int n=0;
char ch;
clrscr();
printf("Enter the SCRABBLE word\n");
ch = getchar();
while(ch!='\n')
{
toupper(ch);
if(ch =='A'||'E'||'I'||'L'||'N'||'O'||'R'||'S'||'T'||'U')
n=n+1;
else if (ch =='D'||'G')
n=n+2;
else if (ch =='B'||'C'||'M'||'P')
n=n+3;
else if (ch =='F'||'H'||'V'||'W'||'Y')
n=n+4;
else if (ch =='K')
n=n+5;
else if (ch =='J'||'X')
n=n+8;
else if (ch =='Q'||'Z')
n=n+10;
ch = getchar();
}
printf("The value is %d",n);
return 0;
}
So what happens when i run this code is that :
Enter the SCRABBLE word
eg: barrier
The value is 7
though it should be 9 as b carries 3 points as noted above the code,a carries 1,r carriers 1,again r 1 point,i carries 1 point and the last two alphabet are one point each so thats 3+1+1+1+1+1+1=9
An expression like ch =='D'||'G' is equal to (ch == 'D')||'G'.
In other words you first perform the sub-expression ch == 'D'. Then you do a logical or using 'G'. The result will always be true since 'G' is non-zero, and everything non-zero is true in C.
You want ch == 'D' || ch == 'G' instead, to check if ch is equal to 'D' or if ch is equal to 'G'.
This is very basic and every good beginners book would have told you so.
In the specific case of the code you show, the very first check will always be true because of this, and you will not check any other cases.
you forgot to get the return value of toupper. Also you don't check it
(according to man 3 toupper, the function will return the same char in case of failure)
Then your conditions aren't good:
if (ch == 'Q' || 'Z') is different from if (ch == 'Q' || ch == 'Z')
The || means if the right or the left condition is true and in the first case (ch == 'Q') is not always true, but 'Z' is always true.
This means your first condition :
if(ch =='A'||'E'||'I'||'L'||'N'||'O'||'R'||'S'||'T'||'U')
is always true
Here are littles corrections you can apply, this might work
char tmp;
ch = getchar();
while(ch!='\n')
{
//Stocking in a tmp char to check return value
tmp = ch;
//Here
ch = toupper(ch);
if (ch == tmp)
{
//Error
break;
}
{...}
else if (ch =='Q'|| ch =='Z')
n += 10;
ch = getchar();
}
Edit : Correction of return value of toupper();

Vowels not counting correctly

I am trying to write a C program to count the number of vowels, keystrokes, and alpha characters. The keystroke counter is working, but the vowel counter is always off by 1 vowel. The alpha counter is not working.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
int keystrokes = 0; //Number of keystrokes.
int letters = 0; //Number of total letters.
int vowels = 0; //Number of vowels.
int i = 0;
char sentence[0]; //Chararacter array specified to users input.
while((sentence[i] = getchar()) != '\n')
{
if(sentence[i] == 'a' || sentence[i] == 'e' || sentence[i] == 'i' || sentence[i] == 'o' ||sentence[i] =='u'|| sentence[i] == 'A' || sentence[i] == 'E' || sentence[i] == 'I' || sentence[i] == 'O' ||sentence[i] == 'U' )
{
++keystrokes;
++letters;
++vowels;
}
else
{
if (isalpha(sentence[i]) == 1) // if character is true
{
++keystrokes;
++letters;
}
else
{
++keystrokes;
i++;
}
}
}
printf("SAMPLE OUTPUT, for EACH sentence above:\n");
printf("Keystrokes %d \n", keystrokes);
printf("Alpha Characters %d \n", letters);
printf("Vowels %d \n", vowels);
return 0;
}
You have a lot of issues here. By saying char sentence[0] you actually say that there is zero bytes of memory to store the input. Accessing sentence[i] will be "out of bounds" and overwrite other parts of memory, leading to undefined behavior.
To start, change char sentence[0] to char sentence[100]. Then look carefully where you increment your counters, i.e. what the if/else flow looks like in your program. To give an example: Currently, when you have a vowel, the check for isalpha() is not reached, nor is the i++.
Your problem is that you have undefined behaviour caused by memory corruption.
char sentence[0];
That declares a 0 character array. Just get rid of the array and the i index. That is, change char sentence[0] to be something like char current_char and then replace all instances of sentence[i] with current_char.
I agree with Alan AU about replacing sentence with get_char. I also changed the (isalpha(sentence[i]) == 1) to (isalpha(sentence[i])).
I admit that I'm still new to programming, but your code did not increment the letters properly until I made that change.

Resources