Cs50 greedy without using <cs50.h> - c

I am solving the greedy algorithm of from the cs50 course without using the cs50 header file. I have written some code. It works fine with numbers as input but when I give it a string or chars as input, it does not prompt me back. I do not know how to solve this issue.
#include <stdio.h>
int main()
{
float c;
int C, nQ, rem1, nD, rem2, nN, rem3;
do
{
printf("O hai! How much change is owed? ");
scanf("%f", &c);
}
while(c<0);
C = c * 100;
nQ = C / 25;
rem1 = C % 25;
nD = rem1 / 10;
rem2 = rem1 % 10;
nN = rem2 / 5;
rem3 = rem2 % 5;
printf("%d\n", nQ+nD+nN+rem3);
}

This is because a float cannot accept a string. You are expecting c to hold other data types when it is just a float variable.
I would suggest you to take input as a string and use atof() to check whether the input is a floating type or not. Something like this:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main()
{
float c;
int C, nQ, rem1, nD, rem2, nN, rem3;
char str[10];
do
{
printf("O hai! How much change is owed? ");
scanf("%s", str);
}
while(atof(str) > 0);
c = atof(str);
C = c * 100;
nQ = C / 25;
rem1 = C % 25;
nD = rem1 / 10;
rem2 = rem1 % 10;
nN = rem2 / 5;
rem3 = rem2 % 5;
printf("%d\n", nQ+nD+nN+rem3);
}
This makes sure that you are using a do while loop only for floating point numbers.

You are expecting c to be negative after your entered a sequence that is not a floating point number.
This is not a valid assumption. If scanf fails, the value of the variable read is undefined.
You need to check the return value of scanf to know if the read was indeed successful. So you can change the code to.
int read;
do
{
printf("O hai! How much change is owed? ");
read = scanf("%f", &c);
if (read == EOF){
// Appropriate error message.
return -1;
}
if (read != 1)
scanf("%*s");
}
while(read != 1 || c < 0);
Now, if the scanf doesn't read a float, it will return 0 and you can continue prompting.
Demo here

Related

How to add the values of c?

#include <stdio.h>
int main() {
// Write C code here
int a, b = 1, c, d;
printf("Value of a:");
scanf("%d", &a);
while (b < a) {
c = b * a;
printf("%d", c);
b++;
}
return 0;
}
I was trying to find the factorial of a number but I don't know how to add the values.
It's written in C.
There are some problems in your code:
the expression c = b * a; computes an intermediary result, but not a useful one. You should compute c = c * b; multiplying the current factorial by the next integer to get the next factorial.
for the expression c = c * b; you must initialize c to 1 before the beginning of the loop.
printf("%d", c); outputs just the digits. You should output a space or a newline to separate the numbers.
scanf("%d", &a) may fail to convert a number from user input, for example if the user typed A. a will stay uninitialized, causing undefined behavior when you use it in further expressions. You should test that scanf() succeeded and returned 1, the number of successful conversions.
Here is a modified version:
#include <stdio.h>
int main() {
int a, b = 1, c = 1;
printf("Value of a:");
if (scanf("%d", &a) == 1) {
while (b < a) {
c = c * b;
printf("%d\n", c);
b++;
}
}
return 0;
}
It is recommended to use the for loop to group the initialization, increment and test of the loop variable in a single place:
#include <stdio.h>
int main() {
int a;
printf("Value of a:");
if (scanf("%d", &a) == 1) {
int c = 1;
for (int b = 1; b < a; b++) {
c = c * b; // one can also write c *= b;
printf("%d\n", c);
}
}
return 0;
}

How do I make the numbers in this C program print in the correct order and not in reverse?

I am new to C so I am having a little difficulty!
I want to take an integer input from the user and add 7 to each of the digit in the input. All of that works, but the digits are printing in the reverse order.
How do i make the digits print in the correct order? I checked other similar questions on Stack overflow but it does not seem to work. Thanks in advance!
int main(void)
{
int numToEncrypt;
printf("Please input a 4-digit number you wish to encrypt: ");
scanf("%d", &numToEncrypt);
while (numToEncrypt > 0)
{
int digit = numToEncrypt % 10;
// do something with digit
digit = (digit + 7)%10;
numToEncrypt /= 10;
printf("number is: %d \n",digit);
}
}
)
Converting the string input to an integer and back is pointless. Just work with the data as a string. eg:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
int c;
if( getenv("V") ) {
printf("Please input the number you wish to encrypt: ");
fflush(stdout);
}
while( (c = getchar()) != EOF ) {
if( isspace(c) ) {
fflush(stdout);
} else if( isdigit(c) ) {
c = '0' + (c - '0' + 7) % 10;
} else {
fprintf(stderr, "Invalid input: %c", c);
return EXIT_FAILURE;
}
putchar(c);
}
}
Note that a huge advantage of doing this is that it is easy to work with ten million digit integers. You will not be able to do that using scanf to convert the string into an integer.
One way is using a variable to specify which digit to process.
#include <stdio.h>
int main(void)
{
int numToEncrypt;
int delta = 1000; // for 4-digit number
printf("Please input a 4-digit number you wish to encrypt: ");
scanf("%d", &numToEncrypt);
while (delta > 0)
{
int digit = (numToEncrypt / delta) % 10;
// do something with digit
digit = (digit + 7)%10;
delta /= 10;
printf("number is: %d \n",digit);
}
}
As this is homework, you could use recursion:
#include <stdio.h>
void print_recursive(int num)
{
// print leading digits
if (num>9)
{
print_recursive(num/10);
}
// print last digits
printf("number is: %d\n", (num+7)%10);
}
int main(void)
{
int number;
printf("Please input a 4-digit number you wish to encrypt: ");
scanf(" %d", &number); // note: You should check the return value!
print_recursive(number);
}
It is not limited to 4 digits.
For a simple program like this, one usually does not bother with a lot of design. However, it is also beneficial to practice software design on simple problems like this, since the knowledge extends to more complicated programs. This is an application of divide and conquer (as a problem solving strategy, not the computer algorithm). The idea being that smaller problems are simpler than larger ones.
In this case, you consider encapsulating the work of "encrypting" to a function, and have the function return the encrypted value. We'll just implement a stub for now, and fill it in later.
int encryptBy7(int input) {
int output = 0;
return output;
}
In addition, we can encapsulate the work of "printing" to a function. And, this is your actual question, if we think about it critically.
void printDigitByDigit(int num, const char *msg) {
printf("stub\n");
}
So your main program would look like:
int main(void) {
int numToEncrypt;
int numEncrypted;
printf("Please input a 4-digit number you wish to encrypt: ");
scanf("%d", &numToEncrypt);
numEncrypted = encryptBy7(numToEncrypt);
printDigitByDigit(numEncrypted, "number is");
return 0;
}
So, your algorithm to encrypt seems to work, so let's just code that up in a way that it stores it as a number.
int encryptBy7(int input) {
int output = 0;
int pow10 = 1;
/* Original program didn't deal with 0 */
if (input == 0) return 0;
while (input > 0) {
int digit = input % 10;
// do something with digit
digit = (digit + 7)%10;
input /= 10;
// build output
output += digit * pow10;
pow10 *= 10;
}
return output;
}
So, now we get to the meat of your question, which is about how to print out the digits starting with the most significant digit. If we see how we built up the output in the previous function, we can reverse the same process of looking at the powers of 10 to find the most significant digit, and then work backwards from there.
void printDigitByDigit(int input, const char *msg) {
int pow10 = 1;
int x = input;
// Find the position of the most significant digit
while (x > 10) {
pow10 *= 10;
x /= 10;
}
// Divide by the input appropriate power of 10 to
// find and print the corresponding digit
while (pow10 > 0) {
int digit = (input / pow10) % 10;
printf("%s: %d\n", msg, digit);
pow10 /= 10;
}
}
Of course, you are free to choose to try to do this as a single program inside of main as you had originally attempted, and the result would probably be a shorter program. I'll leave that as an exercise. However, I would argue that breaking up the program into tasks will provide you more benefit in the long run, and itself is a problem solving tool. Each function becomes easier to think about, and thus an easier problem to solve.

Check to see if scanf is not a float

#define maximum 100
#include <math.h>
#include <stdio.h>
int main () {
float sum, mean, variance, difference;
float sumforvariance, standarddev;
sumforvariance=0;
sum=0;
mean=0;
variance=0;
difference=0;
standarddev=0;
int a, count, b, c;
float insertnum[maximum]
for (a=0; a<maximum; a++) {
scanf("%f",&insertnum[a]);
count ++;
if (insertnum[a]==35.00) {
if (count==1) {
printf ("no data\n");
return 0;
}
break;
}
}
for (b=0; b<count; b++) {
sum+=insertnum[b];
}
mean=sum/count;
for (c=0; c<count; c++) {
difference=insertnum[c]-mean;
sumforvariance=sumforvariance+pow(difference,2);
}
variance=variance/count;
standarddev=sqrt(variance);
printf("mean: %f",mean);
printf("standdev: %f",standarddev);
Hi so I have a simple question. I am trying to calculate a standard deviation and mean for a set of numbers like this
./a.out 12 20 30 etc #
The # is to terminate inputing more numbers. As you can see in the first for loop, I am trying to input the numbers from standard output into an array of floats. The problem is when I enter 35, I do not want to terminate inputting more numbers because its not equal to #. How am I able to enter 35 and continue to enter more numbers until I enter # since they both contain the same numerical value. #=35 and 35=35.
Read you user input in as a string. Sniff for the terminating condition, then convert from string to float. Using the helper function, strtof which is available from #include <stdlib.h>
#define maximum 100
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
float sum, mean, variance, difference;
float sumforvariance, standarddev;
sumforvariance = 0;
sum = 0;
mean = 0;
variance = 0;
difference = 0;
standarddev = 0;
int a, count=0, b, c;
float insertnum[maximum];
for (a = 0; a < maximum; a++) {
char userinput[101] = {0};
userinput[0] = '\0';
scanf("%100s", userinput);
if (userinput[0] == '#')
{
break;
}
insertnum[count] = strtof(userinput, nullptr);
count++;
}
return 0;
}
Also, you forgot to initialize count. And your code was inserting the # read into the array as well. So I fixed that for you.
Aside - I'll never forget the day my computer science professor passionately screamed to the class about the dangers of "reading numbers" from input. Users type characters with the keyboard not numbers. Hence, "validating input" became engrained with me to this day. You might want to consider just letting your loop break whenever the user types anything not a number. A modified version of the loop as follows:
for (a = 0; a < maximum; a++) {
char userinput[101] = {0};
userinput[0] = '\0';
scanf("%100s", userinput);
char* endptr = NULL;
float f = strtof(userinput, &endptr);
if (userinput == endptr)
{
// whatever was typed was not a float
break;
}
insertnum[count] = f;
count++;
}
Check the return value of scanf -- when it successfully converts a float it will return 1 (or more generally, however many conversions in the format string succeeded). So when the input is #, it will return 0 (nothing converted) and leave the # on in the input stream. You can then check the next character to make sure its a #. So you end up with a loop like:
for (a=0; a<maximum && scanf("%f",&insertnum[a]) == 1; a++) {
++count;
}
or even
for (count=0; count < maximum && scanf("%f",&insertnum[count]) == 1; ++count);
if (count == maximum) {
// read the limit -- may be more data
} else {
if (getchar() == '#') {
// got the expected terminator
} else {
// something else caused a problem

Partitioning inputs in scanf

I want to accept the string and the float value in between the '#' is present. I have tried some what like this but it's not working; it is taking the whole input as the string.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[10000];
float number;
scanf("%s#%f",str,&number); //input BMW#23.5 Expected output BMW 23.5
printf("%s %f\n",str,number); //actual output BMW#23.5 0.000000
}
Can anyone help me to solve this?
Get all as a char[] and parse it:
int main()
{
char str[10000];
float number;
scanf("%s", str);
char *at_pos = strrchr(str, '#');
if (at_pos)
{
number = atof(at_pos + 1);
// manage errors in number
printf("%s %f\n", str, number);
}
else
{
// manage error
}
}
//using the "[^#]" can really save your time.
//But you can do a lot in this approach of mine. Not just in that case.
//Feel free to ignore this but if you want to check and understand the logic there, there's the code that i wrote. Then you can just improve it. Tnx.
#include <stdio.h>
int main(void)
{
char str[10000];
char c;//The idea is, collect the input 1 by 1.
float f;
float power = 10;
int counter = 0;//We need this for the string.
c = getchar();//get the first character
str[counter] = c;//store it in the first element
counter++;
c = getchar();//Since we know that the input is string, we assume that there's a next character of course.
while(c != '#')
{
//But what if the user didn't enter a '#' character?
//Do this!
if(c == 10)
{
printf("I can't find the '#' there. =)\n\n");
return 0;
}
str[counter++] = c; //Test the recently collected character if
c = getchar(); //it's '#' or not. If not, then store it
} //in the string and continue to collect the
//next characters then store each of it in
//the string again and again until it reaches the '#'. From there you stop.
//after collecting all the characters, start collecting the numbers.
c = getchar();//collect
f = c - '0';//convert character to digit. I would bet you know this. Then store it in your float variable.
c = getchar();//collect again
//then test the recently collected again. Just like before
while(c != 10 && c != '.')//10 is the ASCII of the <enter> or new line right?. //We will also stop if we encounter '.' (dot)..
{
//while if it's not 10 or dot, add it your float variable. But don't forget the rules. use the power of 10 to.
f = f * 10 + (c - '0');
c = getchar();//collect again.
}
//do this again
c = getchar();
f += (c - '0') / power;//now divide it with power
c = getchar();
power *= 10;//then increase the power.
//Now collect the decimals
while(c != 10)//just like before
{
f += (c - '0') / power; //just do this over and
power *= 10; //over again until
c = getchar(); //it reaches the ASCII 10.
}
//Test it if you got it. =)
printf("%s # %f", str, f);
return 0;
}
//here's the clean code.
#include <stdio.h>
int main(void)
{
char str[1000];
char c;
float f;
float power = 10;
int counter = 0;
c = getchar();
str[counter] = c;
counter++;
c = getchar();
while(c != '#')
{
//But what if the user didn't enter a '#' character?
//Do this!
if(c == 10)
{
printf("I can't find the '#' there. =)\n\n");
return 0;
}
str[counter++] = c;
c = getchar();
}
c = getchar();
f = c - '0';
c = getchar();
while(c != 10 && c != '.')
{
f = f * 10 + (c - '0');
c = getchar();
}
c = getchar();
f += (c - '0') / power;
c = getchar();
power *= 10;
while(c != 10)
{
f += (c - '0') / power;
power *= 10;
c = getchar();
}
printf("%s # %f", str, f);
return 0;
}

Help on string handling in C

In a program to find whether the given number is an Armstrong number, I stored the input no (3 digit) as string as follows.
char input[10];
scanf("%s",&input);
Now I have to calculate cube of each digit by using pow method of math.h as follows.
int a;
a = pow(input[0],3);
By coding like this, I could not get correct result. If I print the value of "a", it shows some irrelevant answer. My doubt is, how to convert from string value to integer value?
You are performing your calculation on the ASCII value of the digit. You'll need to convert it to a numeric value like so:
int digit = input[0] - '0';
int a; a = pow(digit, 3);
There are two problems, both already detailed. The first is that your scanf needs a char*, not a char**. Fix this with what Jeremy said:
scanf("%s", input);
Next, calculate the power correctly, like Adam said:
a = pow(input[0]-'0',3);
You do not need to get the address of the input array using &input. Simply passing input will pass the pointer to your string to scanf(). Your call to scanf() should look like this:
scanf("%s", input);
Another way of doing it, with the address of operator:
scanf("%s", &input[0]);
armstrong numbers are numbers that exhibit the armstron property in any given base, not just base 10.
int isArmstrong(int n, int b)
{
int sum = 0;
int n2 = n;
int nDigits = 0;
while(n2 != 0)
{
nDigits++;
n2 /= b;
}
n2 = n;
for(int i = 0; i < nDigits; i+++)
{
sum += pow(n2 % b, nDigits);
n2 /= b;
}
return sum == n;
}
On the other hand, you may need to replace the power with a more generic one like power = strlen(input)
so the code should look like this.
char input[10];
int power, sum = 0;
scanf("%s", input);
power = strlen(input);
sum += pow(input[0] - '0', power);
/* you need to compare in here */
Doh, I might have spend too much time far of C, because I think most of the answers here miss the final goal... The advice on dropping the & is fine, of course, but there are several other issues with the scanf.
First, it should be OK for throw away code/homework, but it is dangerous: type 11 chars and get a buffer overflow.
Second, IIRC, since you need a number, you should use an int variable and get that. Untested code from a rusty mind:
int inputNumber;
scanf("%d", &inputNumber);
Here you need the & because you no longer have a pointer.
C should do the conversion for you, and you have a safer input.
Other problematic code:
int a = pow(input[0], 3);
You are not making math with the first digit, but with the Ascii value of the first digit! Ie. 49 for 1, 50 for 2...
Since you got a number from my previous correction, divide it by the correct power of 10 to get the digit.
If you prefer to go the string route, use input[0] - '0' at least.
Freehand coding, building on #PhiLho's idea to use an actual integer input:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a, sum, i;
printf("Enter an Armstrong number, an integer in the range 100..999:\n");
if(scanf("%d", &a) != 1)
return EXIT_FAILURE;
if(a < 100 || a > 999)
return EXIT_FAILURE;
/* Now extract digits, and compute sum of cubes. */
for(sum = i = 0; i < 3; i++)
{
sum += pow(a % 10, 3);
a /= 10;
}
printf("sum is: %d\n", sum);
return EXIT_SUCCESS;
}

Resources