This question already has answers here:
What is the behavior of integer division?
(6 answers)
Closed 1 year ago.
I'm doing homework and I have no idea why the %lf selector isn't working. I have to take a line of characters and determine if they can be a floating point or whole number and then print that number. Here's the code:
#include <stdio.h>
int main() {
char ch;
int isNumber = 1, dot = 0, negativeMult = 10;
double result = 0;
printf("\nEnter characters: ");
scanf("%c", &ch);
while (ch != 10) {
if ((ch >= '0' && ch <= '9')) {
if (dot) {
result = result + (ch - '0') / negativeMult;
negativeMult *= 10;
} else {
result = result * 10 + (ch - '0');
}
} else
if (ch == '.')
if (dot)
isNumber = 0;
else
dot = 1;
else {
isNumber = 0;
break;
}
scanf("%c", &ch);
}
if (isNumber)
printf("\nThe number is %lf", result);
else
printf("\nEntered characters are not able to be a number.");
return 0;
}
Edit: I forgot output. Sorry.
Input: Enter characters: 123.648
Output: The number is 123.000000
the error is here:
result = result + (ch - '0') / negativeMult;
(ch - '0') / negativeMult is integer division and it is always 0
it has to be
result = result + (double)(ch - '0') / negativeMult;
some more small errors amendments:
int main(void)
{
char ch;
int isNumber = 1, dot = 0, negativeMult = 10;
double result = 0;
int scanfresult;
printf("\nEnter characters: ");
scanfresult = scanf("%c", &ch);
while (ch != '\n' && scanfresult == 1)
{
if ((ch >= '0' && ch <= '9'))
{
if (dot)
{
result = result + (double)(ch - '0') / negativeMult;
negativeMult *= 10;
}
else
{
result = result * 10 + (ch - '0');
}
}
else if (ch == '.')
if (dot)
isNumber = 0;
else
dot = 1;
else
{
isNumber = 0;
break;
}
scanfresult = scanf("%c", &ch);
}
if (isNumber)
printf("\nThe number is %f", result);
else
printf("\nEntered characters are not able to be a number.");
return 0;
}
https://godbolt.org/z/nTKdjYsz8
Related
I want the programm to read the characters that are between two stars and if there are not two stars, it must print a respective message. For example if the input is 1abc*D2Efg_#!*34567, the output is between first tow stars (letters : 4, digits:1, other:3) any help will be appreciated
int main()
{
int ch,lowercase_lett,digits,other,uppercase_lett,asterisk;
lowercase_lett = 0;
uppercase_lett = 0;
digits = 0;
other = 0;
asterisk = 0;
printf("enter characters : ");
while((ch = getchar()) != '\n' && ch != EOF)
{
if(ch == '*')
{
asterisk++;
}
if(asterisk < 2)
{
printf("\ntwo asterisks not found\n");
}
else
{
if(ch>='a' && ch <= 'z')
{
lowercase_lett++;
}
else if(ch>='A' && ch <= 'Z')
{
uppercase_lett++;
}
else if(ch >='0' && ch <= '9')
{
digits++;
}
else
{
other++;
}
}
}
printf("\n%d letters %d digits and %d other" , lowercase_lett+uppercase_lett,digits,other);
return 0;
}
Count characters when exactly one asterisk has been found. Functions in ctype.h are useful to determine the type of characters.
#include <stdio.h>
#include <ctype.h>
int main(void){
int ch,lowercase_lett,digits,other,uppercase_lett,asterisk;
lowercase_lett = 0;
uppercase_lett = 0;
digits = 0;
other = 0;
asterisk = 0;
printf("enter characters : ");
while((ch = getchar()) != '\n' && ch != EOF)
{
if(ch == '*')
{
asterisk++;
if(asterisk>=2)
{
break;
}
}
else if(asterisk==1)
{
if(islower(ch))
{
lowercase_lett++;
}
else if(isupper(ch))
{
uppercase_lett++;
}else if(isdigit(ch)){
digits++;
}else{
other++;
}
}
}
if(asterisk<2)
{
printf("\ntwo asterisks not found\n");
}
else
{
printf("\n%d letters %d digits and %d other" , lowercase_lett+uppercase_lett,digits,other);
}
return 0;
}
You were almost there, but your code contains some lines in wrong places.
Look at my solution. I just tested and it works for your problem:
#include <stdio.h>
int main(){
int ch;
int lowercase_lett = 0;
int uppercase_lett = 0;
int digits = 0;
int other = 0;
int asterisks = 0;
printf("Enter characters: ");
while((ch = getchar()) != '\n' && ch != EOF)
{
if(asterisks == 2){
break; //End the search
}
else if(ch == '*'){
asterisks++; //Increment until we have 2 *
}
else if(asterisks == 1){
if((ch >= 'a') && (ch <= 'z')){
lowercase_lett++;
}
else if((ch >='A') && (ch <= 'Z')){
uppercase_lett++;
}
else if((ch >= '0') && (ch <= '9')){
digits++;
}
else{
other++;
}
}
}
if (asterisks >= 2){
printf("\n%d letters %d digits and %d other" , lowercase_lett+uppercase_lett,digits,other);
}
else{
printf("\ntwo asterisks not found\n");
}
return 0;
}
#include <stdio.h>
int main(void)
{
int a;
scanf("%d", &a);
for (int i = 0; ; i++)
{
char values[2];
scanf("%c", &values[0]);
scanf("%d", &values[1]);
if (values[0] == '*')
{
a = a * values[1];
printf(" = %d\n", a);
}
else if (values[0] == '+')
{
a = a + values[1];
printf(" = %d\n", a);
}
else if (values[0] == '%')
{
a = a % values[1];
break;
}
}
printf("%d", a);
}
When I input 5 + 3 + 7 + 10 + 2 + 3 + 1 % 11, it would show 5 (because 5%11 = 5). But the + operation didn't work. Can you see what is the problem here?
I think as values[2] is only two variable you need, you can use two different variable to do your job. use one char type variable and one int type variable as you need these two. You have another problem in your code, use a getchar() in the inside of the loop then your code will work fine, cause when you give a integer value as input then take a character value last you enter the new line that goes to that character that is why your code was giving error.
#include <stdio.h>
int main(void){
int a;
scanf("%d", &a);
for (int i = 0; ; i++)
{
getchar();
char ch;
int value;
scanf("%c", &ch);
scanf("%d", &value);
if (ch == '*')
{
a = a * value;
printf(" = %d\n", a);
}
else if (ch == '+')
{
a = a + value;
printf(" = %d\n", a);
}
else if (ch == '%')
{
a = a % value;
break;
}
}
printf("%d", a);
}
There are multiple problems:
value is an array of char: scanning the operator into a char is fine, but the value should be converted into an int variable.
the scanf("%c", ...) will store the next byte into the variable, but after converting an int, the next byte is the pending space or newline, not the '+'. You should use scanf(" %c", ...) to skip the whitespace after the previous conversion.
Here is a modified version:
#include <stdio.h>
int main(void) {
int a;
if (scanf("%d", &a) != 1)
return 1;
for (int i = 0; ; i++) {
char op;
int value;
if (scanf(" %c", &op) != 1)
break;
if (scanf("%d", &value) != 1)
break;
if (op == '*') {
a = a * value;
printf(" = %d\n", a);
} else
if (op == '+') {
a = a + value;
printf(" = %d\n", a);
} else
if (op == '-') {
a = a - value;
printf(" = %d\n", a);
} else
if (op == '%') {
a = a % value;
printf(" = %d\n", a);
} else
if (op == '/') {
a = a / value;
printf(" = %d\n", a);
} else {
printf("invalid operator %c\n", op);
break;
}
}
printf("%d\n", a);
return 0;
}
I'm doing an exercise where i ask the user for an input and then i cypher de input.
Bellow the code:
int main(int argc, char** argv) {
char string[50], cypher[50];
int num, i;
do {
printf("Enter text to cypher: \n");
scanf(" %s", string);
do {
printf("Enter cypher number: ");
scanf(" %d", &num);
while (num > 25) // only 25 letters, get number between >25
{
num -= 25;
}
} while (num <= 0);
for (i = 0; string[i] != '\0'; i++) {
cypher[i] = string[i] + num;
if (cypher[i] > 90 && cypher[i] < 97) // upper case
{
cypher[i] = cypher[i] - 'Z' + 'A' - 1;
}
if (cypher[i] > 122) //lower case
{
cypher[i] = cypher[i] - 'z' + 'a' - 1;
}
}
cypher[i] = '\0';
printf("%s\n", cypher);
}
while (string[0] != '0');
}
I want to exit the do while loop if the user input is '0' when asked to "Enter text to cypher: " without showing the next menssage "Enter cypher number".
Thank you in advance for your help.
after first scanf you should write something like if(string[0] == '0') break;
I made a program that reads a list of grades from a file and calculates the GPA. I have no idea how to properly modularize a program like this, because both the the calculating and the file reading happen simultaneously.
Here is text file contents:
Ariel Lewis
Biology A 4.0
Statistics C 4.0
History A 3.0
Tennis A 1.0
English B 3.0
Here is my code:
#pragma warning (disable:4996)
#include <stdio.h>
#define MAX_LINE 20
#define ERROR -1
float GPA(int, int);
int CoursePoints(int, int);
int GradeToPoints(char);
int main()
{
FILE * fpCredits;
char singleLine[MAX_LINE];
char gradeLetter = '_';
int totalPoints = 0;
int totalCredits = 0;
int credits = 0;
int gradePoint = 0;
int i = 0;
/*
fpCredits = fopen("grades.txt", "w");
fprintf(fpCredits, "Ariel Lewis\n");
fprintf(fpCredits, "Biology A 4.0\n");
fprintf(fpCredits, "Statistics C 4.0\n");
fprintf(fpCredits, "History A 3.0\n");
fprintf(fpCredits, "Tennis A 1.0\n");
fprintf(fpCredits, "English B 3.0\n");
rewind(fpCredits);
*/
fpCredits = fopen("grades.txt", "r");
// DISPLAY INFORMATION
fgets(singleLine, MAX_LINE, fpCredits);
for (i = 0; singleLine[i] != '\n'; i++) {
printf("%c", singleLine[i]);
}
printf("'s Grade Point Average Calculator\n\n");
printf("Course Name Grade Earned Number of Credits Earned\n");
while (!feof(fpCredits)) {
fgets(singleLine, MAX_LINE, fpCredits);
for (i = 0; singleLine[i] != ' '; i++) {
printf("%c", singleLine[i]);
}
printf(" ");
printf("\t");
for (i = 0; singleLine[i] != '\0'; i++) {
if (singleLine[i] == 'A' || singleLine[i] == 'B' || singleLine[i] == 'C' || singleLine[i] == 'D' || singleLine[i] == 'F') {
if (singleLine[i - 1] == ' ' && singleLine[i + 1] == ' ') {
if (singleLine[i + 2] >= '0' && singleLine[i + 2] <= '4') {
credits = singleLine[i + 2] - '0';
}
else {
printf("\n ERROR:FILE_SPACING \n");
break;
}
gradeLetter = singleLine[i];
printf("%c %.1f", gradeLetter, (float)credits);
}
}
}
printf("\n");
}
printf("\n");
rewind(fpCredits);
// CALCULATE INFORMATION
while (!feof(fpCredits)) {
fgets(singleLine, MAX_LINE, fpCredits);
for (i = 0; singleLine[i] != '\0'; i++) {
if (singleLine[i] == 'A' || singleLine[i] == 'B' || singleLine[i] == 'C' || singleLine[i] == 'D' || singleLine[i] == 'F') {
if (singleLine[i - 1] == ' ' && singleLine[i + 1] == ' ') {
if (singleLine[i + 2] >= '0' && singleLine[i + 2] <= '4') {
credits = singleLine[i + 2] - '0';
}
else {
printf("\n ERROR:FILE_SPACING \n");
break;
}
if (singleLine[i] == 'F') {
credits = 0;
}
totalCredits = totalCredits + credits;
gradePoint = GradeToPoints(singleLine[i]);
totalPoints = totalPoints + CoursePoints(gradePoint, credits);
}
}
}
}
rewind(fpCredits);
printf("The GPA for this student is: %.2f and credits earned are: %d.\n\n", GPA(totalPoints, totalCredits), totalCredits);
fclose(fpCredits);
return 0;
}
float GPA(int points, int credits)
{
return (float)points / (float)credits;
}
int CoursePoints(int gradePoints, int credits)
{
return gradePoints * credits;
}
int GradeToPoints(char grade)
{
switch (grade) {
case 'A':
return 4;
case 'B':
return 3;
case 'C':
return 2;
case 'D':
return 1;
case 'F':
return 0;
default:
printf("\n ERROR:DEFAULT \n");
return ERROR;
}
printf("\n ERROR:SKIPPED \n");
return ERROR;
}
First thing to note: modularization is not about simultaneous execution, its ok to read and calculate at the same time, but different modules should perform actual job.
One suggestion how you can make it work is to start with pseudo-code for your algorithm:
total grade = 0;
total grade count = 0;
for every grade in dataset:
print this grade
total grade += this grade;
total grade count++;
print average grade
now, this algorithm does not know anything about files, it works with "dataset", how this can be translated into code, one variant (pseudo c style):
Grade module
Implementation is to put this into grade.h file
struct Grade {
char gradeLetter;
int gradeValue;
int gradeCredits;
}
File based dataset module
Implementation is to put this into FileBaseGradeDataSource.h/c file
FILE* getDataSource() {
///fopen....
}
void closeDataSource(FILE*f) {
///fclose
}
boolean hasMore(FILE*f) {
return !eof(f);
}
Grade getNextGrade(FILE*f) {
// your logic to read and parse string from file
}
Main module
Implementation is to put this into main.c
FILE* datasource = getDataSource();
int totalPoints = 0;
int totalCredits = 0;
while (hasMore(datasource)) {
Grade grade = getNextGrade(datasource);
// printf, save
}
// print average
closeDataSource(datasource);
When I enter anything that evaluates to be false in function isFloat(char array[]) I need to hit enter twice to keep the program running.
If I comment out everything but the fget() command everything requires me to hit enter twice. What could be causing this? I'm flushing stdin properly and the \n is removed by strtok(). Is the printf() function causing problems? I've read that scanf() and fgets() can cause problems when used together. But here they arent.
Problem Area
printf("first number: ");
fgets(input, TEN_THOUSAND, stdin);
strtok(input, "\n");
success = isFloat(input);
if(success)
firstNum = atof(input);
Full Code:
#include<stdio.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int isFloat(char array[])
{
int m = 0;
int periodCount = 0;
for(m=0; array[m] != '\000'; m++)
{
if(array[m] == '1' || array[m] == '2' || array[m] == '3' || array[m] == '4' || array[m] == '5' || array[m] == '6' || array[m] == '7' || array[m] == '8' || array[m] == '9' || array[m] == '0')
{
}
else
{
if(array[m] == '.' && periodCount == 0 && m != 0 && m+1 != '\n')
periodCount = 1;
else
return 0;
}
}
return 1;
}
void eatLine()
{
while (getchar() != '\n');
}
int main()
{
double firstNum = 0.0;
double secondNum = 0.0;
double totalNum = 0.0;
int success = 0;
int TEN_THOUSAND = 10000;
char input[TEN_THOUSAND];
//Outputs assignment header
printf("CS201 - Lab 2 - Number Adder\n\n");
printf("first number: ");
fgets(input, TEN_THOUSAND, stdin);
strtok(input, "\n");
success = isFloat(input);
if(success)
firstNum = atof(input);
while(!success)
{
eatLine();
//The one is for testing purposes
printf("-- bad input --\n");
printf("first number: ");
fgets(input, TEN_THOUSAND, stdin);
strtok(input, "\n");
success = isFloat(input);
if(success)
firstNum = atof(input);
}
printf("second number: ");
fgets(input, TEN_THOUSAND, stdin);
strtok(input, "\n");
success = isFloat(input);
if(success)
secondNum = atof(input);
while(!success)
{
eatLine();
//The one is for testing purposes
printf("-- bad input --\n");
printf("second number: ");
fgets(input, TEN_THOUSAND, stdin);
strtok(input, "\n");
success = isFloat(input);
if(success)
secondNum = atof(input);
}
//adds the numbers
totalNum = firstNum + secondNum;
//Solves ugly formatting problem by firstly including a newline
//after the input is garnered. then it outputs firstNum and totalNum
//in a field of 11 spaces with a newline terminator. This decrements
//11 to 10 on the secondNum line to compensate for the space that the + takes up.
printf("\n%11.2f\n", firstNum);
printf("%s%10.2f\n", "+", secondNum);
printf("-----------\n");
printf("%11.2f\n\n", totalNum);
return 0;
}
When I enter anything that evaluates to be false in function isFloat(char array[]) I need to hit enter twice to keep the program running.
That's because you have a line of code that expects you to enter a line of text.
while(!success)
{
eatLine(); // Culprit