Calculate the cost of cement for a project
up vote
5
down vote
favorite
I am a newbie in a programming, and I just randomly chose a task for training from some group on Facebook. The task is to calculate the cost of cement for a construction project. The input is the number of pounds of cement required (guaranteed not to be a multiple of 120). The store sells cement in 120-pound bags, each costing $45.
Example input: 295.8
Output: 135
#include <stdio.h>
#include <stdlib.h>
#define PRICE 45
#define CAPACITY 120
#define MAXDIGITS 5
int sum(int);
int main(int argc, char *argv)
{
int val = 0;
char inp[MAXDIGITS];
if ((argc > 1) && (argv[1] > 0))
val = strtol(argv[1], NULL, 0);
else
{
do
{
printf("Please input the value of cement: ");
scanf("%s", inp);
val = strtol(inp, NULL, 0);
}
while (!val);
}
if (val)
printf("Money you need: %dn", sum(val));
return 0;
}
int sum(int need)
{
int mon = PRICE;
int n = CAPACITY;
while (n < need)
{
n += CAPACITY;
mon += PRICE;
}
return mon;
}
I'm interested in code style, rational memory usage, etc.
beginner c calculator
New contributor
add a comment |
up vote
5
down vote
favorite
I am a newbie in a programming, and I just randomly chose a task for training from some group on Facebook. The task is to calculate the cost of cement for a construction project. The input is the number of pounds of cement required (guaranteed not to be a multiple of 120). The store sells cement in 120-pound bags, each costing $45.
Example input: 295.8
Output: 135
#include <stdio.h>
#include <stdlib.h>
#define PRICE 45
#define CAPACITY 120
#define MAXDIGITS 5
int sum(int);
int main(int argc, char *argv)
{
int val = 0;
char inp[MAXDIGITS];
if ((argc > 1) && (argv[1] > 0))
val = strtol(argv[1], NULL, 0);
else
{
do
{
printf("Please input the value of cement: ");
scanf("%s", inp);
val = strtol(inp, NULL, 0);
}
while (!val);
}
if (val)
printf("Money you need: %dn", sum(val));
return 0;
}
int sum(int need)
{
int mon = PRICE;
int n = CAPACITY;
while (n < need)
{
n += CAPACITY;
mon += PRICE;
}
return mon;
}
I'm interested in code style, rational memory usage, etc.
beginner c calculator
New contributor
add a comment |
up vote
5
down vote
favorite
up vote
5
down vote
favorite
I am a newbie in a programming, and I just randomly chose a task for training from some group on Facebook. The task is to calculate the cost of cement for a construction project. The input is the number of pounds of cement required (guaranteed not to be a multiple of 120). The store sells cement in 120-pound bags, each costing $45.
Example input: 295.8
Output: 135
#include <stdio.h>
#include <stdlib.h>
#define PRICE 45
#define CAPACITY 120
#define MAXDIGITS 5
int sum(int);
int main(int argc, char *argv)
{
int val = 0;
char inp[MAXDIGITS];
if ((argc > 1) && (argv[1] > 0))
val = strtol(argv[1], NULL, 0);
else
{
do
{
printf("Please input the value of cement: ");
scanf("%s", inp);
val = strtol(inp, NULL, 0);
}
while (!val);
}
if (val)
printf("Money you need: %dn", sum(val));
return 0;
}
int sum(int need)
{
int mon = PRICE;
int n = CAPACITY;
while (n < need)
{
n += CAPACITY;
mon += PRICE;
}
return mon;
}
I'm interested in code style, rational memory usage, etc.
beginner c calculator
New contributor
I am a newbie in a programming, and I just randomly chose a task for training from some group on Facebook. The task is to calculate the cost of cement for a construction project. The input is the number of pounds of cement required (guaranteed not to be a multiple of 120). The store sells cement in 120-pound bags, each costing $45.
Example input: 295.8
Output: 135
#include <stdio.h>
#include <stdlib.h>
#define PRICE 45
#define CAPACITY 120
#define MAXDIGITS 5
int sum(int);
int main(int argc, char *argv)
{
int val = 0;
char inp[MAXDIGITS];
if ((argc > 1) && (argv[1] > 0))
val = strtol(argv[1], NULL, 0);
else
{
do
{
printf("Please input the value of cement: ");
scanf("%s", inp);
val = strtol(inp, NULL, 0);
}
while (!val);
}
if (val)
printf("Money you need: %dn", sum(val));
return 0;
}
int sum(int need)
{
int mon = PRICE;
int n = CAPACITY;
while (n < need)
{
n += CAPACITY;
mon += PRICE;
}
return mon;
}
I'm interested in code style, rational memory usage, etc.
beginner c calculator
beginner c calculator
New contributor
New contributor
edited 2 days ago
200_success
127k15148411
127k15148411
New contributor
asked 2 days ago
Dmitry Khaletskiy
283
283
New contributor
New contributor
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
0
down vote
accepted
Welcome on Code Review
Review
#define PRICE 45
#define CAPACITY 120
#define MAXDIGITS 5
- You define
PRICE
andCAPATITY
as integers, but a price can have cents, and a bag can maybe contains more than a plain amount in pounds, maybe some ounces more. So you should use decimals here.
if ((argc > 1) && (argv[1] > 0))
- Don't compare a
char*
to anint
. This check doesn't insure thatargv[1]
is a valid number. - If the parameter isn't what you want, you can either print the usage and quit, or silently continue and ask for input.
val = strtol(argv[1], NULL, 0);
- You don't validate the program argument.
strtol
can silently fail and return "0". In this case, a good option would be to ask for a good input.
You parse the string to an unsigned integer; but the asked task stand asking a decimal number (and show "295.8" in the example). You could use
strtod
oratof
but since you are a conscientious programmer, you want to check for validity.
So the combo
scanf
/sscanf
(with"%f"
or"%lf"
)` are the solution.
do
{
printf("Please input the value of cement: ");
- Try to put a
n
before your request. It will make the output more clear. Otherwise, it will print on the same line as last output.
scanf("%s", inp);
val = strtol(inp, NULL, 0);
- As above, use
scanf("%lf", ...)
instead (shorter, and you can check for errors)
int sum(int need)
Once what i said above is fixed (price and capacity as double
) your function work fine. However, you can simplify it, by doing the computation in only one line (which can be simplified even more, with libmath).
Here's my corrected version:
#include <stdio.h>
#include <stdlib.h>
#define PRICE 45.
#define CAPACITY 120.
int sum(int);
int main(int argc, char *argv)
{
double need = 0.;
if (argc < 2 || sscanf(argv[1], "%lf", &need) != 1) {
while (printf("nPlease input the amount of cement you need (e.g. 295.8): ") && scanf("%lf", &need) != 1) {
for(int c = 0; c != 'n' && c != EOF; c = getchar());
}
}
printf("For %.02lf pounds you need: $%.02lf!n", need, PRICE * ((int)((int)(need / CAPACITY) * CAPACITY < need) + (int)(need / CAPACITY)));
// or with "#include <math.h>" and the compiler/linker flag "-lm"
//printf("For %.02lf pounds you need: $%.02lf!n", need, PRICE * ceil(need / CAPACITY));
return 0;
}
Agree with you. Only one small mark for your code. If it receive a characters instead of digits, it enters to infinite loop. I think there is no alternative to use additional variable to avoid that possibility.
– Dmitry Khaletskiy
2 days ago
1
@DmitryKhaletskiy fixed
– Calak
2 days ago
Sorry but this code is quite ugly stuff; definitely not something that should be used in place of the OP's much more readable code. The calculations badly need to be split over several lines. Arbitrary checking the return value of printf is fishy. C programming isn't about writing as few LOC as possible, if that comes at the expensive of readability.
– Lundin
12 hours ago
while (... scanf("%lf", &need) != 1) {
is an infinite loop on end-of-file, input error.
– chux
8 hours ago
(int)
unnecessarily limits a floating-pint function to theint
range - promoting a weak programing paradigm. Robust code would userint()
,round()
,trunc()
etc. instead.
– chux
8 hours ago
|
show 4 more comments
up vote
-1
down vote
Buffer overflow
Consider what entering "295.8"
does.
#define MAXDIGITS 5
char inp[MAXDIGITS];
printf("Please input the value of cement: ");
scanf("%s", inp);
Code used the dangerous scanf("%s", inp);
with no width limits. scanf("%s", inp);
being ignorant of the size of inp
, stored the 5 read characters and the appended null character.
This results in undefined behavior (UB). Code may work as expected today and fail is strange ways tomorrow.
I recommend to only use fgets()
for user input. After reading a line of user input, it is saved as a string. Then parse the string.
No need for such a tight buffer size. Recommend twice the expected max width needed.
#define BUFFER_SIZE (2*MAXDIGITS + 1)
char buffer[BUFFER_SIZE];
printf("Please input the value of cement: ");
fflush(stdout); // Insure output is seen before reading
fgets(buffer, sizeof buffer, stdin);
double val = strtod(buffer, NULL, 0);
Interestingly, I didn't know this version ofstrtod
with 3 parameters. What's the last is used for?
– Calak
1 hour ago
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
Welcome on Code Review
Review
#define PRICE 45
#define CAPACITY 120
#define MAXDIGITS 5
- You define
PRICE
andCAPATITY
as integers, but a price can have cents, and a bag can maybe contains more than a plain amount in pounds, maybe some ounces more. So you should use decimals here.
if ((argc > 1) && (argv[1] > 0))
- Don't compare a
char*
to anint
. This check doesn't insure thatargv[1]
is a valid number. - If the parameter isn't what you want, you can either print the usage and quit, or silently continue and ask for input.
val = strtol(argv[1], NULL, 0);
- You don't validate the program argument.
strtol
can silently fail and return "0". In this case, a good option would be to ask for a good input.
You parse the string to an unsigned integer; but the asked task stand asking a decimal number (and show "295.8" in the example). You could use
strtod
oratof
but since you are a conscientious programmer, you want to check for validity.
So the combo
scanf
/sscanf
(with"%f"
or"%lf"
)` are the solution.
do
{
printf("Please input the value of cement: ");
- Try to put a
n
before your request. It will make the output more clear. Otherwise, it will print on the same line as last output.
scanf("%s", inp);
val = strtol(inp, NULL, 0);
- As above, use
scanf("%lf", ...)
instead (shorter, and you can check for errors)
int sum(int need)
Once what i said above is fixed (price and capacity as double
) your function work fine. However, you can simplify it, by doing the computation in only one line (which can be simplified even more, with libmath).
Here's my corrected version:
#include <stdio.h>
#include <stdlib.h>
#define PRICE 45.
#define CAPACITY 120.
int sum(int);
int main(int argc, char *argv)
{
double need = 0.;
if (argc < 2 || sscanf(argv[1], "%lf", &need) != 1) {
while (printf("nPlease input the amount of cement you need (e.g. 295.8): ") && scanf("%lf", &need) != 1) {
for(int c = 0; c != 'n' && c != EOF; c = getchar());
}
}
printf("For %.02lf pounds you need: $%.02lf!n", need, PRICE * ((int)((int)(need / CAPACITY) * CAPACITY < need) + (int)(need / CAPACITY)));
// or with "#include <math.h>" and the compiler/linker flag "-lm"
//printf("For %.02lf pounds you need: $%.02lf!n", need, PRICE * ceil(need / CAPACITY));
return 0;
}
Agree with you. Only one small mark for your code. If it receive a characters instead of digits, it enters to infinite loop. I think there is no alternative to use additional variable to avoid that possibility.
– Dmitry Khaletskiy
2 days ago
1
@DmitryKhaletskiy fixed
– Calak
2 days ago
Sorry but this code is quite ugly stuff; definitely not something that should be used in place of the OP's much more readable code. The calculations badly need to be split over several lines. Arbitrary checking the return value of printf is fishy. C programming isn't about writing as few LOC as possible, if that comes at the expensive of readability.
– Lundin
12 hours ago
while (... scanf("%lf", &need) != 1) {
is an infinite loop on end-of-file, input error.
– chux
8 hours ago
(int)
unnecessarily limits a floating-pint function to theint
range - promoting a weak programing paradigm. Robust code would userint()
,round()
,trunc()
etc. instead.
– chux
8 hours ago
|
show 4 more comments
up vote
0
down vote
accepted
Welcome on Code Review
Review
#define PRICE 45
#define CAPACITY 120
#define MAXDIGITS 5
- You define
PRICE
andCAPATITY
as integers, but a price can have cents, and a bag can maybe contains more than a plain amount in pounds, maybe some ounces more. So you should use decimals here.
if ((argc > 1) && (argv[1] > 0))
- Don't compare a
char*
to anint
. This check doesn't insure thatargv[1]
is a valid number. - If the parameter isn't what you want, you can either print the usage and quit, or silently continue and ask for input.
val = strtol(argv[1], NULL, 0);
- You don't validate the program argument.
strtol
can silently fail and return "0". In this case, a good option would be to ask for a good input.
You parse the string to an unsigned integer; but the asked task stand asking a decimal number (and show "295.8" in the example). You could use
strtod
oratof
but since you are a conscientious programmer, you want to check for validity.
So the combo
scanf
/sscanf
(with"%f"
or"%lf"
)` are the solution.
do
{
printf("Please input the value of cement: ");
- Try to put a
n
before your request. It will make the output more clear. Otherwise, it will print on the same line as last output.
scanf("%s", inp);
val = strtol(inp, NULL, 0);
- As above, use
scanf("%lf", ...)
instead (shorter, and you can check for errors)
int sum(int need)
Once what i said above is fixed (price and capacity as double
) your function work fine. However, you can simplify it, by doing the computation in only one line (which can be simplified even more, with libmath).
Here's my corrected version:
#include <stdio.h>
#include <stdlib.h>
#define PRICE 45.
#define CAPACITY 120.
int sum(int);
int main(int argc, char *argv)
{
double need = 0.;
if (argc < 2 || sscanf(argv[1], "%lf", &need) != 1) {
while (printf("nPlease input the amount of cement you need (e.g. 295.8): ") && scanf("%lf", &need) != 1) {
for(int c = 0; c != 'n' && c != EOF; c = getchar());
}
}
printf("For %.02lf pounds you need: $%.02lf!n", need, PRICE * ((int)((int)(need / CAPACITY) * CAPACITY < need) + (int)(need / CAPACITY)));
// or with "#include <math.h>" and the compiler/linker flag "-lm"
//printf("For %.02lf pounds you need: $%.02lf!n", need, PRICE * ceil(need / CAPACITY));
return 0;
}
Agree with you. Only one small mark for your code. If it receive a characters instead of digits, it enters to infinite loop. I think there is no alternative to use additional variable to avoid that possibility.
– Dmitry Khaletskiy
2 days ago
1
@DmitryKhaletskiy fixed
– Calak
2 days ago
Sorry but this code is quite ugly stuff; definitely not something that should be used in place of the OP's much more readable code. The calculations badly need to be split over several lines. Arbitrary checking the return value of printf is fishy. C programming isn't about writing as few LOC as possible, if that comes at the expensive of readability.
– Lundin
12 hours ago
while (... scanf("%lf", &need) != 1) {
is an infinite loop on end-of-file, input error.
– chux
8 hours ago
(int)
unnecessarily limits a floating-pint function to theint
range - promoting a weak programing paradigm. Robust code would userint()
,round()
,trunc()
etc. instead.
– chux
8 hours ago
|
show 4 more comments
up vote
0
down vote
accepted
up vote
0
down vote
accepted
Welcome on Code Review
Review
#define PRICE 45
#define CAPACITY 120
#define MAXDIGITS 5
- You define
PRICE
andCAPATITY
as integers, but a price can have cents, and a bag can maybe contains more than a plain amount in pounds, maybe some ounces more. So you should use decimals here.
if ((argc > 1) && (argv[1] > 0))
- Don't compare a
char*
to anint
. This check doesn't insure thatargv[1]
is a valid number. - If the parameter isn't what you want, you can either print the usage and quit, or silently continue and ask for input.
val = strtol(argv[1], NULL, 0);
- You don't validate the program argument.
strtol
can silently fail and return "0". In this case, a good option would be to ask for a good input.
You parse the string to an unsigned integer; but the asked task stand asking a decimal number (and show "295.8" in the example). You could use
strtod
oratof
but since you are a conscientious programmer, you want to check for validity.
So the combo
scanf
/sscanf
(with"%f"
or"%lf"
)` are the solution.
do
{
printf("Please input the value of cement: ");
- Try to put a
n
before your request. It will make the output more clear. Otherwise, it will print on the same line as last output.
scanf("%s", inp);
val = strtol(inp, NULL, 0);
- As above, use
scanf("%lf", ...)
instead (shorter, and you can check for errors)
int sum(int need)
Once what i said above is fixed (price and capacity as double
) your function work fine. However, you can simplify it, by doing the computation in only one line (which can be simplified even more, with libmath).
Here's my corrected version:
#include <stdio.h>
#include <stdlib.h>
#define PRICE 45.
#define CAPACITY 120.
int sum(int);
int main(int argc, char *argv)
{
double need = 0.;
if (argc < 2 || sscanf(argv[1], "%lf", &need) != 1) {
while (printf("nPlease input the amount of cement you need (e.g. 295.8): ") && scanf("%lf", &need) != 1) {
for(int c = 0; c != 'n' && c != EOF; c = getchar());
}
}
printf("For %.02lf pounds you need: $%.02lf!n", need, PRICE * ((int)((int)(need / CAPACITY) * CAPACITY < need) + (int)(need / CAPACITY)));
// or with "#include <math.h>" and the compiler/linker flag "-lm"
//printf("For %.02lf pounds you need: $%.02lf!n", need, PRICE * ceil(need / CAPACITY));
return 0;
}
Welcome on Code Review
Review
#define PRICE 45
#define CAPACITY 120
#define MAXDIGITS 5
- You define
PRICE
andCAPATITY
as integers, but a price can have cents, and a bag can maybe contains more than a plain amount in pounds, maybe some ounces more. So you should use decimals here.
if ((argc > 1) && (argv[1] > 0))
- Don't compare a
char*
to anint
. This check doesn't insure thatargv[1]
is a valid number. - If the parameter isn't what you want, you can either print the usage and quit, or silently continue and ask for input.
val = strtol(argv[1], NULL, 0);
- You don't validate the program argument.
strtol
can silently fail and return "0". In this case, a good option would be to ask for a good input.
You parse the string to an unsigned integer; but the asked task stand asking a decimal number (and show "295.8" in the example). You could use
strtod
oratof
but since you are a conscientious programmer, you want to check for validity.
So the combo
scanf
/sscanf
(with"%f"
or"%lf"
)` are the solution.
do
{
printf("Please input the value of cement: ");
- Try to put a
n
before your request. It will make the output more clear. Otherwise, it will print on the same line as last output.
scanf("%s", inp);
val = strtol(inp, NULL, 0);
- As above, use
scanf("%lf", ...)
instead (shorter, and you can check for errors)
int sum(int need)
Once what i said above is fixed (price and capacity as double
) your function work fine. However, you can simplify it, by doing the computation in only one line (which can be simplified even more, with libmath).
Here's my corrected version:
#include <stdio.h>
#include <stdlib.h>
#define PRICE 45.
#define CAPACITY 120.
int sum(int);
int main(int argc, char *argv)
{
double need = 0.;
if (argc < 2 || sscanf(argv[1], "%lf", &need) != 1) {
while (printf("nPlease input the amount of cement you need (e.g. 295.8): ") && scanf("%lf", &need) != 1) {
for(int c = 0; c != 'n' && c != EOF; c = getchar());
}
}
printf("For %.02lf pounds you need: $%.02lf!n", need, PRICE * ((int)((int)(need / CAPACITY) * CAPACITY < need) + (int)(need / CAPACITY)));
// or with "#include <math.h>" and the compiler/linker flag "-lm"
//printf("For %.02lf pounds you need: $%.02lf!n", need, PRICE * ceil(need / CAPACITY));
return 0;
}
edited 2 days ago
answered 2 days ago
Calak
1,963314
1,963314
Agree with you. Only one small mark for your code. If it receive a characters instead of digits, it enters to infinite loop. I think there is no alternative to use additional variable to avoid that possibility.
– Dmitry Khaletskiy
2 days ago
1
@DmitryKhaletskiy fixed
– Calak
2 days ago
Sorry but this code is quite ugly stuff; definitely not something that should be used in place of the OP's much more readable code. The calculations badly need to be split over several lines. Arbitrary checking the return value of printf is fishy. C programming isn't about writing as few LOC as possible, if that comes at the expensive of readability.
– Lundin
12 hours ago
while (... scanf("%lf", &need) != 1) {
is an infinite loop on end-of-file, input error.
– chux
8 hours ago
(int)
unnecessarily limits a floating-pint function to theint
range - promoting a weak programing paradigm. Robust code would userint()
,round()
,trunc()
etc. instead.
– chux
8 hours ago
|
show 4 more comments
Agree with you. Only one small mark for your code. If it receive a characters instead of digits, it enters to infinite loop. I think there is no alternative to use additional variable to avoid that possibility.
– Dmitry Khaletskiy
2 days ago
1
@DmitryKhaletskiy fixed
– Calak
2 days ago
Sorry but this code is quite ugly stuff; definitely not something that should be used in place of the OP's much more readable code. The calculations badly need to be split over several lines. Arbitrary checking the return value of printf is fishy. C programming isn't about writing as few LOC as possible, if that comes at the expensive of readability.
– Lundin
12 hours ago
while (... scanf("%lf", &need) != 1) {
is an infinite loop on end-of-file, input error.
– chux
8 hours ago
(int)
unnecessarily limits a floating-pint function to theint
range - promoting a weak programing paradigm. Robust code would userint()
,round()
,trunc()
etc. instead.
– chux
8 hours ago
Agree with you. Only one small mark for your code. If it receive a characters instead of digits, it enters to infinite loop. I think there is no alternative to use additional variable to avoid that possibility.
– Dmitry Khaletskiy
2 days ago
Agree with you. Only one small mark for your code. If it receive a characters instead of digits, it enters to infinite loop. I think there is no alternative to use additional variable to avoid that possibility.
– Dmitry Khaletskiy
2 days ago
1
1
@DmitryKhaletskiy fixed
– Calak
2 days ago
@DmitryKhaletskiy fixed
– Calak
2 days ago
Sorry but this code is quite ugly stuff; definitely not something that should be used in place of the OP's much more readable code. The calculations badly need to be split over several lines. Arbitrary checking the return value of printf is fishy. C programming isn't about writing as few LOC as possible, if that comes at the expensive of readability.
– Lundin
12 hours ago
Sorry but this code is quite ugly stuff; definitely not something that should be used in place of the OP's much more readable code. The calculations badly need to be split over several lines. Arbitrary checking the return value of printf is fishy. C programming isn't about writing as few LOC as possible, if that comes at the expensive of readability.
– Lundin
12 hours ago
while (... scanf("%lf", &need) != 1) {
is an infinite loop on end-of-file, input error.– chux
8 hours ago
while (... scanf("%lf", &need) != 1) {
is an infinite loop on end-of-file, input error.– chux
8 hours ago
(int)
unnecessarily limits a floating-pint function to the int
range - promoting a weak programing paradigm. Robust code would use rint()
, round()
, trunc()
etc. instead.– chux
8 hours ago
(int)
unnecessarily limits a floating-pint function to the int
range - promoting a weak programing paradigm. Robust code would use rint()
, round()
, trunc()
etc. instead.– chux
8 hours ago
|
show 4 more comments
up vote
-1
down vote
Buffer overflow
Consider what entering "295.8"
does.
#define MAXDIGITS 5
char inp[MAXDIGITS];
printf("Please input the value of cement: ");
scanf("%s", inp);
Code used the dangerous scanf("%s", inp);
with no width limits. scanf("%s", inp);
being ignorant of the size of inp
, stored the 5 read characters and the appended null character.
This results in undefined behavior (UB). Code may work as expected today and fail is strange ways tomorrow.
I recommend to only use fgets()
for user input. After reading a line of user input, it is saved as a string. Then parse the string.
No need for such a tight buffer size. Recommend twice the expected max width needed.
#define BUFFER_SIZE (2*MAXDIGITS + 1)
char buffer[BUFFER_SIZE];
printf("Please input the value of cement: ");
fflush(stdout); // Insure output is seen before reading
fgets(buffer, sizeof buffer, stdin);
double val = strtod(buffer, NULL, 0);
Interestingly, I didn't know this version ofstrtod
with 3 parameters. What's the last is used for?
– Calak
1 hour ago
add a comment |
up vote
-1
down vote
Buffer overflow
Consider what entering "295.8"
does.
#define MAXDIGITS 5
char inp[MAXDIGITS];
printf("Please input the value of cement: ");
scanf("%s", inp);
Code used the dangerous scanf("%s", inp);
with no width limits. scanf("%s", inp);
being ignorant of the size of inp
, stored the 5 read characters and the appended null character.
This results in undefined behavior (UB). Code may work as expected today and fail is strange ways tomorrow.
I recommend to only use fgets()
for user input. After reading a line of user input, it is saved as a string. Then parse the string.
No need for such a tight buffer size. Recommend twice the expected max width needed.
#define BUFFER_SIZE (2*MAXDIGITS + 1)
char buffer[BUFFER_SIZE];
printf("Please input the value of cement: ");
fflush(stdout); // Insure output is seen before reading
fgets(buffer, sizeof buffer, stdin);
double val = strtod(buffer, NULL, 0);
Interestingly, I didn't know this version ofstrtod
with 3 parameters. What's the last is used for?
– Calak
1 hour ago
add a comment |
up vote
-1
down vote
up vote
-1
down vote
Buffer overflow
Consider what entering "295.8"
does.
#define MAXDIGITS 5
char inp[MAXDIGITS];
printf("Please input the value of cement: ");
scanf("%s", inp);
Code used the dangerous scanf("%s", inp);
with no width limits. scanf("%s", inp);
being ignorant of the size of inp
, stored the 5 read characters and the appended null character.
This results in undefined behavior (UB). Code may work as expected today and fail is strange ways tomorrow.
I recommend to only use fgets()
for user input. After reading a line of user input, it is saved as a string. Then parse the string.
No need for such a tight buffer size. Recommend twice the expected max width needed.
#define BUFFER_SIZE (2*MAXDIGITS + 1)
char buffer[BUFFER_SIZE];
printf("Please input the value of cement: ");
fflush(stdout); // Insure output is seen before reading
fgets(buffer, sizeof buffer, stdin);
double val = strtod(buffer, NULL, 0);
Buffer overflow
Consider what entering "295.8"
does.
#define MAXDIGITS 5
char inp[MAXDIGITS];
printf("Please input the value of cement: ");
scanf("%s", inp);
Code used the dangerous scanf("%s", inp);
with no width limits. scanf("%s", inp);
being ignorant of the size of inp
, stored the 5 read characters and the appended null character.
This results in undefined behavior (UB). Code may work as expected today and fail is strange ways tomorrow.
I recommend to only use fgets()
for user input. After reading a line of user input, it is saved as a string. Then parse the string.
No need for such a tight buffer size. Recommend twice the expected max width needed.
#define BUFFER_SIZE (2*MAXDIGITS + 1)
char buffer[BUFFER_SIZE];
printf("Please input the value of cement: ");
fflush(stdout); // Insure output is seen before reading
fgets(buffer, sizeof buffer, stdin);
double val = strtod(buffer, NULL, 0);
answered 7 hours ago
chux
12.2k11342
12.2k11342
Interestingly, I didn't know this version ofstrtod
with 3 parameters. What's the last is used for?
– Calak
1 hour ago
add a comment |
Interestingly, I didn't know this version ofstrtod
with 3 parameters. What's the last is used for?
– Calak
1 hour ago
Interestingly, I didn't know this version of
strtod
with 3 parameters. What's the last is used for?– Calak
1 hour ago
Interestingly, I didn't know this version of
strtod
with 3 parameters. What's the last is used for?– Calak
1 hour ago
add a comment |
Dmitry Khaletskiy is a new contributor. Be nice, and check out our Code of Conduct.
Dmitry Khaletskiy is a new contributor. Be nice, and check out our Code of Conduct.
Dmitry Khaletskiy is a new contributor. Be nice, and check out our Code of Conduct.
Dmitry Khaletskiy is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208380%2fcalculate-the-cost-of-cement-for-a-project%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown