Program returns wrong value - c

I have a problem in the following part of my code in C:
// reading pairs of parameters from input file
while((read = fscanf(input_file, "%d %d\n", &type, &col)) > 0 ) {
// checking reading errors
if (read != 2 || (type < 0 && type > 4) || (col > 9)) {
printf("Invalid input file format\n");
return 2;
}
// putting tetromino corresponding to given parameters to the field
if (put_tetromino(field, type, col) != 0) {
// if result is not 0, the tetromnio is out of range. Returning error
printf("Tetromino is out of field\n");
return 2;
}
}
The input file looks like this:
5 0
3 9
2 9
2 4
..
In the above part of the code I want to check if the input file has the correct format.
I should have 2 columns: the first (type) has to be a value between 0 and 4 and the second (col) has to be a value between 0 and 9. If the input file contains a wrong format, for example:
9 8
4 9
2 5
..
I want to return 2. But the program doesn't return 2, it returns 0 at the end of the main-function.

The expression (type < 0 && type > 4) is always false - a number can't be both larger than four and less than zero. You should use an || instead of an && there:
if (read != 2 || type < 0 || type > 4 || col > 9) {

actually a number can not be at a time bigger than 4 and smaller than 0 . and also you need to check if col < 0. it should look like this if (read != 2 || (type < 0 || type > 4) || (col<0 || col > 9))
for your need you need to this.
// reading pairs of parameters from input file
while((read = fscanf(input_file, "%d %d\n", &type, &col)) > 0 ) {
// checking reading errors
if (read != 2 || (type < 0 || type > 4) || (col<0 || col > 9)) {
printf("Invalid input file format\n");
return 2;
}
// putting tetromino corresponding to given parameters to the field
if (put_tetromino(field, type, col) != 0) {
// if result is not 0, the tetromnio is out of range. Returning error
printf("Tetromino is out of field\n");
return 2;
}
}

Related

lowest and biggest values problems with conditions in C

trying to find the smallest and largest value in the array, I'm getting the wrong small value. Why ?
biggerY=lowerY=arrY[0];
for(int loop2 = 1; loop2<10; loop2++)
{
if(arrY[loop2]>biggerY && arrY[loop2] != 0)
biggerY=arrY[loop2];
if(arrY[loop2]<lowerY && arrY[loop2] != 0)
lowerY=arrY[loop2];
}
my input :
1 2
2 1
The values ​​on the right are saved in my array(arrY[10]).
expected biggerY: 2
expected lowerY : 1
my output for biggerY : 2
my output for lowery : 0 (but it should be 1)
thanks.
The problem with your code is that irrespective of the size of the arrY array, you run the loop till 10. You should run the loop till its size.Assuming the size of arrY is in the variable n
biggerY=lowerY=arrY[0];
for(int loop2 = 1; loop2<n; loop2++)
{
if(arrY[loop2]>biggerY && arrY[loop2] != 0)
biggerY=arrY[loop2];
if(arrY[loop2]<lowerY && arrY[loop2] != 0)
lowerY=arrY[loop2];
}

If else statement troubles in C

I am trying to input a seat number of "15" into this function and get the char value of 'A'. However, for some reason every time I input a number that should be a type 'A'(because its remainder doesn't equal any of the aforementioned values) it gets stuck in the 'M' else if statement. I really do not understand why and would like some help if you have time :)
char whatTypeOfSeat(int seatNumber){
if((seatNumber % 6) == 0 || seatNumber % 6 == 1 || seatNumber == 1) {
typeOfSeat = 'W';
}
else if((seatNumber % 6) == 2 || (seatNumber % 6) == 5|| seatNumber == 5,2 ) {
typeOfSeat = 'M';
}
else {
typeOfSeat = 'A';
}
return typeOfSeat;
}
This does not do what you think it does:
seatNumber == 5,2
If you want to check against both values, you need separate conditionals
else if((seatNumber % 6) == 2 || (seatNumber % 6) == 5|| seatNumber == 5 || seatNumber == 2 ) {

Testing if a number goes evenly into 6? [duplicate]

This question already has answers here:
modulo operation on negative numbers [duplicate]
(2 answers)
Closed 5 years ago.
I am trying to see if two input numbers (integers) including negative numbers go into 6 evenly (remainder is 0). This is the code I was trying.
if((in1)%6 == 0 && (in2)%6 == 0){
printf("Divisible: both\n");
}
else if((in1)%6 == 0 && (in2)%6 > 0){
printf("Divisible: only %i\n",in1);
}
else if((in1)%6 > 0 && (in2)%6 == 0){
printf("Divisible: only %i\n",in2);
}
else{
printf("Divisible: neither\n");}
This works for all positive integer but for any negatives the printed code is always "Divisible: neither" any help as to how I can show both positive and negative numbers divisible by six with a remainder of 0 would be really helpful
You could use != 0 instead of > 0. In C, % of negative number will give a negative result (or zero).
This is because a / b is defined as truncation-towards-zero since C99 (in C90 it was implementation-defined). And a % b is defined as a - (a / b) * b.
Note that you actually do not need this test at all; you can rely on the behaviour of if...else not entering the else case if the if case was satisfied, e.g.:
if ( in1 % 6 == 0 && in2 % 6 == 0 )
{
// ...
}
else if ( in1 % 6 == 0 )
{
// would not reach here if in2 % 6 == 0
}
else if ( in2 % 6 == 0 )
{
// would not reach here if in1 % 6 == 0
}
else
Another consideration, rather than oblige code to test numbers 3 times, re-write to perform only 2 test on the numnbers.
if (in1 % 6) {
if (in2 % 6) {
printf("Divisible: both\n");
} else {
printf("Divisible: only %i\n",in1);
}
} else {
if (in2 % 6) {
printf("Divisible: only %i\n",in2);
} else {
printf("Divisible: neither\n");}
}
}

'if' statement in C not executing even though conditions are met

I'm a first time programmer trying to complete a simple command line program as part of the first assignment for an online course I am taking, but I seem to have hit a roadblock that I can't figure out with GDB or my own research.
After hours of rewrites, and hours of debugging, I finally got the code below to compile. The program is supposed to take a credit card number as an input, and then check whether it's valid per the specifications of the assignment. I used a test number from here: PayPal Test Credit Cards
The odd thing is, when I enter an AMEX card number, it correctly produces the text "AMEX", but when I try a Visa or a Master Card, it prints "INVALID".
In GDB I broke at the Verify function and it seems to incorrectly skip these two if/else if statements without proceeding to the Checksum function even though conditions appear to be met.
if (firstDigit == 4 && totalDigits == (13 | 16) && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Visa.
...
else if (firstDigit == 5 && secondDigit == (1 | 2 | 3 | 4 | 5) && totalDigits == 16 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Mastercard.
...
The AMEX line of code that correctly executes is:
else if (firstDigit == 3 && secondDigit == (4 | 7) && totalDigits == 15 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid American Express.
The arguments for all three lines seem to be formatted exactly the same. That is far as I could get in GDB though. I would print totalDigits, firstDigit, and secondDigit in GDB right before stepping through the above two non-executing lines and everything looked correct. So I'm stumped, why is the AMEX line executing, but not the others?
Thanks in advance everyone. This is the first program after hello.c that I've tried to write, so I am open to absolutely any criticism or suggestions if it looks like I'm doing something weird/wrong.
Full code:
checker.c
#include <stdio.h>
#include <stdlib.h>
int MAX = 16;
int* DigitSort(unsigned long long x, int* array);
int Verify(int* array);
int main (void)
{
int* output = malloc (sizeof(int) * (MAX + 2)); // creates a blank array for the individual digits of the card number.
unsigned long long userInput = 0;
do
{
printf("Please enter a credit card number:\n");
scanf("%lld", &userInput);
}
while (userInput <= 0); // checks to make sure the user entered a number.
switch(Verify(DigitSort(userInput, output))) // sorts the user's input into individual digits and verifies the card type and validity.
{
case 1 :
printf("VISA\n");
break;
case 2 :
printf("MASTERCARD\n");
break;
case 3 :
printf("AMEX\n");
break;
case 0 :
printf("INVALID\n");
break;
default :
printf("INVALID\n");
}
free(output);
return 0;
}
int Verify(int* array) // verifies whether or not a card number is valid. Must pass the function a sorted array of individual digits.
{
int* cardNumber = array;
int firstDigit = cardNumber[0];
int secondDigit = cardNumber[1];
int totalDigits = 0;
int Checksum(int* cardNumber, int totalDigits);
int i = 0;
while (firstDigit >= 1 && cardNumber[i] >= 0) // this step counts the number of digits in the array.
{
totalDigits = totalDigits + 1;
i++;
}
if (firstDigit == 4 && totalDigits == (13 | 16) && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Visa.
{
return 1;
}
else if (firstDigit == 5 && secondDigit == (1 | 2 | 3 | 4 | 5) && totalDigits == 16 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Mastercard.
{
return 2;
}
else if (firstDigit == 3 && secondDigit == (4 | 7) && totalDigits == 15 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid American Express.
{
return 3;
}
else // if the card number doesn't match any of the above conditions or fails the checksum, an 'I' for Invalid is returned.
{
return 0;
}
}
int* DigitSort(unsigned long long x, int* array) // takes a long long as input and sorts it into individual digits
{
int* arrayReversed = malloc (sizeof(int) * (MAX + 2)); // creates a new array to hold the reversed order of digits.
int i = 0;
arrayReversed[0] = 0;
if (i < (MAX - 1) && x >= 10)
{
do
{
arrayReversed[i] = x % 10;
x = x / 10;
i++;
}
while (i < (MAX -1) && x >= 10);
}
if (i < MAX && x >= 1 && x <= 9)
{
arrayReversed[i] = (int) x;
x = (x - x);
}
if (x == 0)
{
int j = 0;
do
{
array[j] = arrayReversed[i]; // sorts the digits from the reversed array and places them into the sorted array.
j++;
i--;
}
while (j < MAX && i >= 0);
array[j] = -1;
}
free(arrayReversed);
return array;
}
int Checksum(int* cardNumber, int totalDigits)
{
int sum1 = 0;
int sum2 = 0;
int i = (totalDigits - 2);
int j = (totalDigits - 1);
while (i >= 0)
{
sum1 = ((cardNumber[i] * 2)%10) + ((cardNumber[i] * 2)/10) + sum1;
i -= 2;
}
while (j >= 0)
{
sum2 = (cardNumber[j] + sum2);
j -= 2;
}
if (((sum1 + sum2) % 10) == 0)
{
return 0;
}
else
{
return 1;
}
}
Your first problem is here:
if (firstDigit == 4 && totalDigits == (13 | 16) && ...
You need to write:
if (firstDigit == 4 && (totalDigits == 13 || totalDigits == 16) && ...
Your first check is looking for 0x1D == 29 as the number of digits (because, as paisanco points out in a comment, the | operator is the bitwise OR operator), and no credit card needs 29 digits (yet, and not for a long time to come). Note the extra parentheses for clarity and accuracy. Don't mess around risking removing them β€” the code won't work properly again. And in general, be explicit if your condition has both && and || operators and use parentheses to group terms explicitly.
You have similar problems elsewhere. As it happens, (4 | 7) is the same value as 7, so the condition works when the second digit is 7 (but not when it is 4). But it doesn't mean what you intended it to mean.
Computer languages don't work the same as human languages. Get used to writing out the condition somewhat more verbosely. Some other languages provide shorthands for these conditions; C is not such a language.

How to compare number against an interval? ( x > (1,10))

How to compare one number against an interval.
Is there any way to shorten this expression:
if ((x%10) == 1 || (x%10) == 2 || (x%10) == 3 || (x%10) == 4 ) // ... till number 9.
Assuming x is an integer, there are only 10 possible values. And the only one not checked, 0, is also the only false integer.
if (x % 10)
{
...
You can check it like this:
if(!(x%10)) {
}

Resources