If statements not working inside while loop - c

Only the 'strlen' function is being executed by the program.
The if statements inside this while loop do not even work...
#include<stdio.h>
#include<string.h>
#include <ctype.h>
main()
{
char cMessage[100];
int cLow = 0, cUp = 0, cSpec = 0, cSpace = 0, cNum = 0;
printf("Enter your message: ");
scanf("%s", cMessage);
int x = 0;
while(cMessage[x] != 0)
{
x = strlen(cMessage);
printf("Total characters: %d", x);
if(islower(cMessage[x]))
{
printf("\nTotal Lowercase Letters: %d", cLow);
cLow++;
}
else if(isupper(cMessage[x]))
{
printf("\nTotal Uppercase Letters: %d", cUp);
cUp++;
}
else if(isalnum(cMessage[x]))
{
printf("\nTotal Special Characters: %d", cSpec);
cSpec++;
}
else if(isspace(cMessage[x]))
{
printf("\nTotal Lowercase Letters: %d", cSpace);
cSpace++;
}
else if(isdigit(cMessage[x]))
{
printf("\nTotal Lowercase Letters: %d", cNum);
cNum++;
}
}
x++;
}
I cannot figure out the cause of this issue...
What may be the cause of this?
EDIT: So here's the revised code of the program, the only problem that I have now is that the spaces are not being counted. And btw, is there a specific function used to 'count' special characters? I've used 'isalnum' and I realized it was wrong
#include<stdio.h>
#include<string.h>
#include <ctype.h>
#include<conio.h>
main(){
char cMessage[100];
int cLow=0, cUp=0, cSpec=0, cSpace=0, cNum=0;
printf("Enter your message: ");
scanf("%s", cMessage);
int x=0;
while(cMessage[x]){
printf("Total characters: %d", strlen(cMessage));
while(cMessage[x]!=0){
if(islower(cMessage[x])){ cLow++;}
if(isupper(cMessage[x])){ cUp++;}
if(isalnum(cMessage[x])){ cSpec++; }
if(isspace(cMessage[x])){ cSpace++; }
if(isdigit(cMessage[x])){ cNum++; }
x++;
}
printf("\nTotal Lowercase Letters: %d", cLow);
printf("\nTotal Uppercase Letters: %d", cUp);
printf("\nTotal Special Characters: %d", cSpec);
printf("\nTotal Spaces: %d", cSpace);
printf("\nTotal Numbers: %d", cNum);
getch();
}
}

The x = strlen(cMessage); will give you the length of cMessage which is always the index of the last item + 1.
for example if: cMessage = "The" and x = strlen(cMessage) , then:
x = 3
cMessage[0] = 'T'
cMessage[1] = 'h'
cMessage[2] = 'e'
cMessage[3] = NULL terminator // equivalence to 0
Note that there is usually a NULL terminator after the last character.
So as you can see, the while condition is always false after the first pass.
Try to use a separate variable to iterate through cMessage.
Also you need to consider putting variables like cUp++' before the 'printf statements.
A more elegant alternative will be using for statement instead of while.
Also note that isalnum(cMessage[x]) is interfering with if(isdigit(cMessage[x])) so, it is better to use separate if statements and git rid of else if, moreover, if you want to count special characters you have to negates isalnum to be: if(!isalnum(cMessage[x])).
At last your input will not accept sentences (word with spaces between them), so you have to consider replacing:
scanf("%s", cMessage);
with
scanf("%[^\n]s",&cMessage);

You take x as the lenght of your string. So that's one longer then your Array. After the full array is always a 0 to show the program the array is not longer. This way you can never go in the if's

cMessage[x] after x=strlen(cMessage) is always 0. String contains chars from 0 till x - 1, char at post x is 0. Thus any if-condition is false.
I suppose x=strlen(cMessage); is not needed and must be removed, x++ must be three last operator in the loop body, since you want to count chars of different kinds.
printf("Total characters: %zu", strlen(cMessage));
while(cMessage[x] != 0) {
if(islower(cMessage[x])) {
...
}
x++;
}
%d is not proper format for size_t type on 64-bit platform. Read this: How can one print a size_t variable portably using the printf family?

Related

C program does not recognize my input for 'max'

Hi I keep trying to figuure this out but my input keeps getting ignored, thanks in advance
#include <stdio.h>
#include <stdlib.h>
int main(){
float a, b, a0, b0,i;
char ans;
printf("Fibonacci search method\n\nEnter the function:\n");
printf("\nEnter the intervals over which the Fibonacci method must be applied:\n");
for (i = 1; i <= 1; i++) {
printf("a0 = ", i);
scanf("%f", & a);
printf("bo = ", i);
scanf("%f", & b);
}
printf("Narrow down on either a maximiser or a minimiser (max/min): \n", ans);
scanf(" %c", &ans);
while(ans == 'max'){
printf("maximum selected");
}
printf("minimum selected");
return 0;
}
First of all, you're comparing a single char to a whole string, so you need to modify your ans variable declaration to make it a string, like:
char ans[4]
Keep in mind, this will have a maximum size of 3. If you need to store a bigger string, you'll need to modify this.
Then, after doing this, using a while to do that comparison isn't correct. It's better to implement an if-else. And, inside that, the comparison you're doing is wrong. You need to compare strings, not chars, so you need to use strcmp() function, like:
strcmp(ans,"max") == 0
If this function returns a 0, it means both strings are equal.
Another thing to comment is that you will need to modify your scanf to scan a string, not a char, the new one will be scanf("%3s", &ans);.
And let me tell you one more thing. The for you're using has no sense. You're using a for with parameters i = 1; i <= 1; i++. That means i will start the buckle fulfilling the conditions to break it, so it will only be executed once. In other words, the code inside that for will be executed just once, no matter if it's inside or outside the for.
Anyway, and to sum up, here's your new code:
int main(){
float a, b, a0, b0,i;
char ans[4];
printf("Fibonacci search method\n\nEnter the function:\n");
printf("\nEnter the intervals over which the Fibonacci method must be applied:\n");
for (i = 1; i <= 1; i++) {
printf("a0 = ", i);
scanf("%f", & a);
printf("bo = ", i);
scanf("%f", & b);
}
printf("Narrow down on either a maximiser or a minimiser (max/min): \n", ans);
scanf("%3s", &ans);
if(strcmp(ans,"max") == 0)
printf("maximum selected");
else
printf("minimum selected");
return 0;
}

Isalpha is requiring an identifier

Here's my code:
#include <stdio.h>
#include <ctype.h>
main(){
float input;
printf("Input: ");
scanf("%f", &input);
if (isalpha(input) || (input) < 0)){
printf("Input is an alphabet or is lesser than 0");
} else {
printf("Input is correct. %f is a number larger than 0", input);
}
}
I want the code to detect if input is a number larger than 0, or is it an alphabet. However, I am getting this error:
8: error: identifier expected
What does it mean to my code's execution? How am I supposed to run the code successfully?
Correct parentheses in if:
if ( isalpha(input) || (input < 0) )
In addition, you need to check the return value of scanf() whether there was input or not. In the case of no input, the return value would be 0 or in case of multiple inputs how many succeeded. In your case, you can use the return value to determine whether a float was input or not.
The main() should return an int and always initialize your variables.
Example (live):
#include <stdio.h>
#include <ctype.h>
int main()
{
float input = 0.0f;
printf("Input: ");
int ret = scanf("%f", &input);
if ( ret == 0 )
{
printf("ERROR: Input is NOT a float!\n");
return -1;
}
if ( input < 0.0f )
{
printf("Input is less than 0");
}
else
{
printf("Input is correct. %f is a number larger than 0", input);
}
return 0;
}
Your parentheses aren't opened/closed properly.
Maybe your ide/compiler is taking care of it, but it should be int main()
isalpha() will behave unexpectedly with float values. Try avoiding that.
First of all you are missing int declaring main,
int main()
Also,you have excessive bracket in line
if (isalpha(input) || (input) < 0)){
Scanf uses %f to read floats. What your program will do is accept any ascii character and I suppose that wasn't your intention.
I am still not sure what you need, but you could try something like this as a starting point. It does not handle all possible inputs, and will erroneously classify an input such as #42 as alphabet or lesser than 0, which is questionable, but you can iterate on this and hopefully get to a more polished version.
#include <stdio.h>
#include <ctype.h>
int main(){
float input;
printf("Input: ");
if (scanf("%f", &input) && input >= 0){
printf("Input is correct. %f is a number larger than 0", input);
} else {
printf("Input is an alphabet or is lesser than 0");
}
}
Explanation
We save the value in input, if compatible with the %f format:
float input;
Prompt for the user:
printf("Input: ");
This condition is made of two parts; the first part is the scanf, that will try to read input, and if successful will evaluate to 1, which is true, so the second part input >= 0 will be evaluated, and if input is indeed >= 0 we print the first message.
if (scanf("%f", &input) && input >= 0){
printf("Input is correct. %f is a number larger than 0", input);
Else we print the second message.
} else {
printf("Input is an alphabet or is lesser than 0");
}

Scanning Values Until Getting a Significant Character in C

For my homework, I am trying to code a calculator which can also calculate average of taken numbers. I don't want to ask for number of numbers because our teacher don't want it in that way. So I thought of scanning values until the user presses "p". But as you would guess, the numbers are float and "p" is a character. What I want to do is assigning the value scanned to both of them if it is possible. I tried different ways, played with the codes but it isn't working properly. So I am seeking your advice.
It prints a value when p is inputted as like 3rd, 5th, 7th (oddth) number (sometimes right, sometimes wrong but I can fix it if I figure this out). But it doesn't print a value in other occasions and expects infinite inputs from the user.
This is the code I have written for this. scanf("%f %c", &number1, &pause); command is where I want to know about, actually.
#include<stdio.h>
float number1, number2, i, result;
char pause;
int main() {
scanf("%f", &number1);
i = 0;
while (pause != 'p') {
number2 = number1 + number2;
scanf("%f %c", &number1, &pause);
i++;
}
result = number2 / (i - 1);
printf("%f", result);
}
Use double not floats if there is no specific reason to do so (like using uC without double FPU).
You do not initialize the variables
Always check the result of the I/O operation.
#include <stdio.h>
int main ()
{
double number1= 0, number2 = 0, i = 0, result = 0;
char pause = 0;
char line[128];
while (pause != 'p')
{
if(fgets(line, sizeof(line), stdin))
{
if(sscanf(line, "%lf %c",&number1, &pause) != 2)
{
printf("Wrong input - try again\n");
pause = 0;
continue;
}
number2 = number1 + number2;
i++;
}
else
{
// do something with I/O error
}
}
result = number2 / (i-1);
printf("%lf",result);
}
You can play with it yourself : https://onlinegdb.com/Hy3y94-3r
I noticed 3 problems with your code.
First I would advise you to use meaningful variables names. number1, number2, etc. and the i which represents the number of inputs given can be an int instead of a float.
Secondly, you lack of printing to the user what's going on in your program; it's better to have messages like "enter your number, do you wanna stop? the result is...etc".
Lastly, having two inputs in one line of code can make it hard to debug, knowing that reading strings and characters in C is already hard for beginners. For example, %c does not skip whitespace before converting a character and can get newline character from the previous data entry.
Here is my fix: I changed some variables' names, printed some messages and read the two inputs in two different lines with adding scanf(" %c") with the space to avoid that problem.
#include<stdio.h>
float sum, temp, result;
int nb;
char pause;
int main () {
pause='a';
while (pause != 'p'){
printf("Enter your number: ");
scanf("%f",&temp);
sum+=temp;
nb++;
printf("type 'p' if you want to stop: ");
scanf(" %c",&pause);
}
result = sum / nb;
printf("the average is : %f",result);
}
I tested it, should work fine
Edit: after explaining that you don't want to ask the user each time, here is how the code should work (the case that the user don't input a float is not treated, and just take it as zero
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
float sum, temp, result;
int nb;
char input[50];
int main () {
sum=0;
nb=0;
printf("Enter your numbers, then type 'p' to stop\n");
do{
printf("Enter your next number: ");
scanf("%s", input);
if(strcmp(input,"p")!=0)
{
float temp= atof(input);
sum+=temp;
nb++;
}
}while(strcmp(input,"p")!=0);
if(nb!=0)
result = sum / nb;
printf("\nThe average is : %f",result);
}

Getting an Array from user? C programming

My console keeps on crashing after entering a few numbers. I am trying to get an array of 10 numbers from the user thru the console and then taking count of positives, negatives, evens, and odds. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int pos, neg, even, odd;
int nums[10];
printf("Give me 10 numbers: ");
pos = neg = even = odd = 0;
for(int i = 0; i < 10; i++){
scanf(" %d", nums[i]);
if(nums[i] > 0){
pos++;
if(nums[i] % 2 == 0){
even++;
}
else{
odd++;
}
}
else{
neg++;
}
}
printf("Positives: %d, Negatives: %d, Evens: %d, Odds: %d\n", pos, neg, even, odd);
return 0;
}
In your code,
scanf(" %d", nums[i]);
should be
scanf(" %d", &(nums[i]));
or,
scanf(" %d", nums+i);
as you need to pass the pointer to variable as the format specifier's argument in scanf() .
To elaborate, %d expects a pointer to int and what you're supplying is an int variable. it invokes undefined behavior.
That said,
Always check the return value of scanf() to ensure proper scanning.
int main() should be int main(void) to conform to the standard.
Modify scanf like scanf(" %d", &nums[i]);
scanf(" %d", nums[i]);
Scanf expects a pointer to a location to write to, and you're not giving it one.
Change your scanf to:
scanf(" %d", &(nums[i]));
to make your program work.
With this change I tested your program with stdin of
20 10 9 1 39 1 2 2 31 1
And recieved output:
Give me 10 numbers: Positives: 10, Negatives: 0, Evens: 4, Odds: 6
ideone of the thing for your testing purposes.
Change scanf(" %d", nums[i]); to scanf(" %d", &nums[i]);, because scanf() needs addresses. The parentheses around nums[i] isn't necessary, and may effect readability.
Also note that 0 is even, but not negative.
When scanf is usedto convert numbers, it expects a pointer to the corresponding type as argument, in your case int *:
scanf(" %d", &nums[i]);
This should get rid of your crash. scanf has a return value, namely the number of conversions made or the special value EOF to indicate the end of input. Please check it, otherwise you can't be sure that you have read a valid number.
When you look at your code, you'll notice that you don't need an array. Afterreading the number, you don't do aything with the array. You just keep a tally of odd, even and so on numbers. That means you just need a single integer to store the current number. That also extends your program nicely to inputs of any length.
Here's a variant that reads numbers until the end of input is reached (by pressing Ctrl-D or Ctrl-Z) or until a non-number is entered, e.g. "stop":
#include <stdlib.h>
#include <stdio.h>
int main()
{
int count = 0;
int pos = 0;
int neg = 0;
int even = 0;
int odd = 0;
int num;
while (scanf("%d", &num) == 1) {
count++;
if (num > 0) pos++;
if (num < 0) neg++;
if (num % 2 == 0) even++;
if (num % 2 != 0) odd++;
}
printf("%d numbers, of which:\n", count);
printf(" %d positive\n", pos);
printf(" %d negative\n", neg);
printf(" %d even\n", even);
printf(" %d odd\n", odd);
return 0;
}
Change scanf statement after for loop to
scanf(" %d", &nums[i]);

What should I do to remove the comma after the last term?

#include <stdio.h>
int main()
{
int n1, n2, temp, n, d, p;
printf("Enter two numbers(The limits of your prime numbers): ");
scanf("%d %d", &n1, &n2);
if (n1>n2)
{
temp=n1;
n1=n2;
n2=temp;
}
printf("The prime numbers between %d and %d are: ", n1, n2);
for(n=n1;(n<=n2)||(n<2000);++n)
{
p=1;
for(d=2; d<=n/2; ++d)
{
if(n%d==0)
{
p=0;
break;
}
}
if(p==1)
{
if (n==1)
{continue;}
printf("%d",n);
//I don't know what to put here so that the last term won't have a comma
printf(", ");
}
}
return 0;
}
I'm trying to print prime numbers between two intervals(inclusive) but the last terms always have a comma. I need a way to prevent the comma from printing after the last term. The commas are followed by a space before the next term.
For example(My current situation):
Input:1 10
Output:2, 3, 5, 7,
What it should be:2, 3, 5, 7
I forgot to mention that once "n" exceeds 2000 it should stop printing..
A very common problem, independent from the programming language and more of a logical thinking exercise. In this case, you can't tell when you're printing the last number, but you can tell when you print the first. Use that knowledge and put the ", " first in your loop, omitting it on the first iteration.
edit: eg use a flag for this: if (firstRun) { firstRun = 0; } else { fputs(", ", stdout); }
Print the comma separately before the number, and have a conditional stating if this is the first prime number, don't print the comma. Otherwise print it out....
Try this
(n<=n2)?printf(","):(n<2000?printf(","):printf("\n"))
Something like this:
char *separator = "";
for (...) {
...
printf("%s%d", separator, n);
separator = ",";
}
i have a great solution for your question use
printf("\b\b "); //2 time space after \b\b
it include before return 0; statement like :
if(p==1)
{
if (n==1)
{continue;}
printf("%d",n);
//I don't know what to put here so that the last term won't have a comma
printf(", ");
}
}
printf("\b\b "); //here insert code
return 0;
it will help surely

Resources