Why doesn't this program stop? - c

My instructor has asked us to follow the variables through this code and determine when the variables change. He says the inputs should be
8, 4, 2, 1
I have compiled and run the code to he me understand it but it doesn't stop. It just ouputs "Feed me two numbers please:" over and over. Any help is greatly appreciated.
#include <stdio.h>
main ()
{
int a;
int b;
int c=0;
int d=0;
int e=0;
int f=0;
while (c == 0 || a + b !=0){
printf("Feed me two numbers please: \n");
scanf ("%d %d", &a, &b);
if (c == c + 1){
printf("Welcome to my world!\n\n");
}
if (c = 0){
d = a + b;
e = d;
}
else if (a + b > d){
d = a + b;
}
else if (a + b < e){
e = a + b;
}
if (a < f){
f=a;
}
c = c + 1;
}
printf("Now hear this:%d %d\n\n", d, e, f);
}

In
if (c = 0)
you're assigning 0 to c, the expression of the assignment returns the assigned value, so the expression will be always evaluated to false as it's equivalent to if(0), it should be if(c == 0).
Also
if (c == c + 1)
doesn't make any sense, what exactly do you mean? I think it should be c > 0.
In all cases, you should use the debugger, it can save you a lot of time, and will help you to really understand your code.

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;
}

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;
}

C Program returning a series of question marks at the end or sometimes, returning nothing

My program is supposed to erase /**/ comments, condense white spaces, and remove line splices of the input.
**edit: scroll down to problem update below.
Here is my code:
#include <stdio.h>
void ass(), f1(), f2(), f3();
int mainRunner();
int a, b;
int main() {
ass();
mainRunner();
}
void ass() {
a = getchar();
b = getchar();
}
int mainRunner() {
while ( a != EOF ) {
f1();
f2();
f3();
putchar(a);
a = b;
b = getchar();
}
}
// Removes Line Splices
void f1() {
if ((a == '\\') && (b == '\n')) {
a = getchar();
b = getchar();
mainRunner();
}
}
//Removes Comments in the /*...*/ form
void f2() {
if ((a == '/') && (b == '*')) {
while ((a != '*') || (b != '/')) {
a = b;
b = getchar();
}
a = getchar();
b = getchar();
mainRunner();
}
}
//Condenses White Spaces
void f3() {
if ((a == ' ') && (b == ' ')) {
a = b;
b = getchar();
mainRunner();
}
}
When I run the testscript (testscript 1):
a b c
d e
f
g
hifealkfja;efa faekjf;ale feafaefa
This is returned
a b c
d e
f
g
hifealkfja;efa faekjf;ale feafaefa
????????????????
When I run this testscript (testscript 2):
start linesplice NOW!\
This should be connected with first line.Comment begins here:/*fjelajfal;efjael$
fe;ajfe;fe8/Comment Ends.
Series of 5 spaces between the letters:a b
Series of 10 spaces between the letters:c d
Increasing number of spaces between letters from 1 space:e f g h i
Nothing happens and the command line cursor goes to the very left.
I appreciate any feedback, thanks.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Problem Update:
Reduced the issue above by doing what chux suggested. Now I only have the question mark problem. I made a fix so that putchars wouldn't be waiting in the stack and output a whole bunch of EOFs at the end, but why are there still two question marks? Here's my new code:
#include <stdio.h>
void ass();
int mainRunner();
int a, b;
int main() {
ass();
mainRunner();
}
void ass() {
a = getchar();
b = getchar();
}
int mainRunner() {
while ( a != EOF ) {
// Removes Line Splices
if ((a == '\\') && (b == '\n')) {
a = getchar();
b = getchar();
mainRunner();
}
//Removes Comments in the /*...*/ form
if ((a == '/') && (b == '*')) {
while ((a != '*') || (b != '/')) {
a = b;
b = getchar();
}
a = getchar();
b = getchar();
mainRunner();
}
//Condenses White Spaces
if ((a == ' ') && (b == ' ')) {
a = b;
b = getchar();
mainRunner();
}
if (a == EOF) {
break;
}
else {
putchar(a);
a = b;
b = getchar();
}
}
}
When I run the second test script from above (with an asterisk added to end the comment), my program outputs:
start linesplice NOW!This should be connected with first line.Comment
begins here:Comment Ends. Series of 5 spaces between the letters:a b
Series of 10 spaces between the letters:c d Increasing number of
spaces between letters from 1 space:e f g h i ??
Notice the two question marks at the end.
Note: the program works fine for the first test script.
Given OP's first testscript:
The if in f1() is never true.
The if in f2() is never true.
f3() effectively recurses into itself via mainRunner() when multiple space are encountered. Upon seeing EOF, the recursion stops, and unwinds. mainRunner() performs putchar(a); with EOF in a with each unwinding.
Removing mainRunner(); in f1(), f2(), & f3() may help.
The test code has 1 + 13 + 1 + 2 sequences of 2 spaces. This causes 17 recursive calls. Upon unwinding putchar(EOF) is called 16 times creating the '?'.
In OP's 2nd testscript. f2() gets into an infinite loop with
while ((a != '*') || (b != '/')) {
a = b;
b = getchar();
}
as there is no escape should getchar() return EOF.

My number converter(decimal to base 2-16) prints numbers in opposite order

I've been working on a program that, when executed, asks for two numbers, the first being any decimal number, the second number being the base (2-16) which you wish to convert to. It works great, except one thing. Every output is backwards. Which is to be expected, it takes remainders and outputs them in the order they are calculated. However I want them to come out in the opposite order. I was thinking about setting up a loop and having the remainders stored in an array, then loop through the array backwards and spit out the information. But I'm new to C and i cannot get it to work! Tell me what you think!
Any help would be very appreciated. I've been stuck on this for a while.
#include <stdio.h>
#include <stdlib.h>
int main(void){
int x, y, z, c; //Sets up variables to be used in program
printf("Please enter two integers: "); //Asks for user input
scanf("%d", &x);
scanf("%d", &y); //stores input
printf("%d\n", x);
printf("%d\n", y);
printf(" \n");
if(y < 2 || y > 16){
printf("You have entered incorrect information.\n");
return 0;
} //bug checks
else if(y > 1 && y < 17){
while(x != 0){
c = (x%y);
x = (x/y); // Loops numbers until a 0 value is reached, can be used with
// any Base
if( c == 10){
c = printf("A");
}else if( c == 11){
c = printf("B");
}else if( c == 12){
c = printf("C");
}else if( c == 13){
c = printf("D");
}else if( c == 14){
c = printf("E");
}else if( c == 15){
c = printf("F");
}else{
printf("%d", c);
}
// Returns for each remainer option
}
printf("\n");
}
// Returns for each remainer option
printf("\n");
}
Declare
int i = 0;
int rev[50];
and change your code as
if( c == 10){
rev[i++] = 'A' ;
}else if( c == 11){
rev[i++] = 'B' ;
}else if( c == 12){
rev[i++] = 'C' ;
}else if( c == 13){
rev[i++] = 'D' ;
}else if( c == 14){
rev[i++] = 'E' ;
}else if( c == 15){
rev[i++] = 'F' ;
}else{
rev[i++] = 48 + c;
}
// Returns for each remainer option
}
printf("\n");
}
while(--i >= 0)
printf("%c", rev[i]);
Keep all the remainders into an character array and print the array in reverse
Another approach would be a recursive approach (which I wouldn't recommend for very long sequences, but since an integer has a limited number of digits, you can know how deep your recursion would be). It would look something like this (not tested, and somewhat pseudo-codey):
printnum(int n, int b)
{ int r;
if (n < b)
output n;
else
{ r = n % b;
printnum(n/b, b)
output r;
}
}
A good optimizer might even be able to transparently convert that to non-recursive code when you compile.

error with printf statement? (In C) *Update*

For clarification purposes I need the program to print the numbers that are input for a and b, not the actual letters a and b.
Okay here's the revised program per yall's suggestions:
int main (int argc, char *argv[])
{
int a; /*first number input*/
int b; /*second number input*/
a = atoi(argv[1]); /*assign to a*/
b = atoi(argv[2]); /*assign to b*/
if (a < b)
printf("%s\n", a < b); /* a is less than b*/
else {
printf("%s\n", a >= b); /* a is greater than or equal to b*/
}
if (a == b)
printf("%s\n", a == b); /* a is equal to b*/
else {
printf("%s\n", a != b); /* a is not equal to b*/
}
return 0;
} /* end function main*/
lol, now when I run the program I get told
8 [main] a 2336 _cygtls::handle_exceptions: Error while dumping state
Segmentation fault
What the heck does that mean? (If you haven't noticed by now I am pretty hopeless at this stuff lol).
You're asking printf() to print the values of the boolean expressions (which always resolve to 1 or 0 for true and false respectively).
You probably want your code to look more like:
if (a < b)
printf("%s\n", "a < b"); /* a is less than b*/
else {
printf("%s\n", "a >= b"); /* a is greater than or equal to b*/
}
To display the results as strings.
This line:
if (a = b)
shouldn't it be
if (a == b)
Same here:
printf("%d\n", a = b); /* a is equal to b*/
should be
printf("%d\n", a == b); /* a is equal to b*/
Based on your edit, I think you're looking for this:
#include <stdio.h>
int main (int argc, char *argv[]) {
int a; /*first number input*/
int b; /*second number input*/
a = atoi(argv[1]); /*assign to a*/
b = atoi(argv[2]); /*assign to b*/
if (a < b)
printf("%d < %d\n", a, b); /* a is less than b*/
else
printf("%d >= %d\n", a, b); /* a is greater than or equal to b*/
if (a == b)
printf("%d == %d\n", a, b); /* a is equal to b*/
else
printf("%d != %d\n", a, b); /* a is not equal to b*/
return 0;
}
This code:
wfarr#turing:~$ ./foo 1 2
1 < 2
1 != 2
printf("%s\n", a == b);
"%s" prints a string. a == b isn't a string, it's a boolean expression, resulting in 1 (true) or 0 (false).
So, your printf() attempts to print characters until it finds a null byte, starting at the position of the boolean expression... desaster.
Your problem is, you are trying to substitute logical expressions instead of integers. All of the above (a > b) ... evaluate to true or false (except a = b which assigns the value of b to a). What you should be doing, if you are trying to return the larger value, is the following:
printf("%d\n", a > b ? a : b)
This says if a is greater than b, print a, otherwise b.
Edit: I think what you are actually looking for is to print out the words "a > b" etc. In which case, put them in the printf. When you place %d in the printf, it subs a specified integer value into that spot in the string.
I believe you want the following:
if(a > b)
printf("a > b\n");
else
printf("b >= a\n");
Is that correct?
I'm assuming you want something like this...
Input:
a = 5, b = 7
Output:
5 < 7
5 != 7
If so, you need to print the integers a and b, as well as a string in between to show the relationship.
if( a < b ) {
printf( "%d < %d\n", a, b );
}
else {
printf( "%d >= %d\n", a, b );
}
// follow similar pattern for the next if/else block..

Resources