How to extend my multiple loop conditions? - c

My code
#include <stdlib.h>
#include <stdio.h>
int main()
{
int i=0;
int j=0;
size_t count=0;
float numbers[20][100];
float velocity[21][101];
char *line = NULL;
FILE *myFile;
myFile = fopen("vel.txt", "r");
if (myFile == NULL)
{
printf("Error Reading File\n");
exit (0);
}
while(i < 20 && getline(&line, &count, myFile)!=-1) {
int len = 0, pos = 0;
j = 0;
while(j < 100 && 1 == sscanf(line + pos, "%f%n", &numbers[i][j++], &len))
pos += len;
i++;
}
free(line);
fclose(myFile);
i=1;
for( j = 0; j < 101; j++ )
{
if( j == 1 )
{
velocity[i][j]=numbers[i][j];
}
else if ( j == 101 )
{
velocity[i][j]=numbers[i][j];
}
else
{
velocity[i][j]=(numbers[i][j-1]+numbers[i][j])/2;
}
}
for (j=0 ; j<101 ; j++) {
printf("\n%f", velocity[i][j]);
}
}
I need to calculate velocities for 21,101 two dimensional mesh.If i==1 ,that is my code above and works fine.The sam conditions apply if i==21.But for all other values (2 to 20) calculations are different.How should I change
if( i== from 2 to 20 &&j == 1 )
{
do something
}
else if (i== from to to 20 && j == 101 )
{
do something 2
}
else(means i goes from 2,20 j goes from 2,100)
{
do something 3
}

Do you want something like this: if(i >= 2 %% i <= 20)? Means: 2 <= i <= 20 or if i is greater or the same as 2 and i is lower or the same as 20 it is true.
If your example:
if(i >= 2 && i <= 20 && j == 1)
{
//do something
}
else if(i >= 2 && i <= 20 && j == 101)
{
//do something 2
}
else if(i >= 2 && i <= 20 && j >= 2 && j <= 100) //means i goes from 2,20 j goes from 2,100
{
//do something 3
}
or is there anything I missed?

Related

Segmentation fault when there is just one value as input

My code seems to be working fine, but I get a Segmentation fault when there is just one value as input. It should print a square shape based on a number as character input.
test case : ["2", "2"]
"oo\noo\n"
test case: ["", ""]
""
test case : ["2"]
SIGSEGV (signal 11)
#include <string.h>
#include <stdlib.h>
void my_square(int *x, int *y)
{
int i , j;
if (*x == 0 || *y == 0) {
printf("");
}
else{
for(i = 0; i < *x; i++){
for(j = 0; j < *y; j++){
if(*x<=2 && j == 0){
printf("o");
}else if(*x<=2 && j == 1){
printf("o\n");
}else if(*y<=2 && i == 0){
printf("o");
}else if(*y<=2 && i == 1){
printf("o\n");
}else{
//printf(" i: %d, j: %d ", i, j);
if(i == 0 && j == 0 || i == *y-1 && j == 0 || i == 0 && j == *x-1 || i == *y-1 && j == *x-1){
printf("o");
}
if(i >= 1 && j == 0 && i != *y-1) {
printf("|");
}
if(i >= 1 && j == *x-1 && i != *y-1) {
printf("|");
}
if(i == 0 && j >= 1 && j != *y-1|| i == *x-1 && j >= 1 && j != *y-1){
printf("-");
}
if(i >= 1 && j >= 1 && i < *x-1 && j < *y-1){
printf(" ");
}
if(j == *x-1){
printf("\n");
}
}
//printf("> %d, %d", i, j);
}
}
}
}
int main(int ac, char **av)
{
int x = atoi(av[1]);
int y = atoi(av[2]);
my_square(&x, &y);
return 0;
}```
You should always check ac before accessing av, otherwise it may lead to undefined behaviour (and cause a segmentation fault).
That's how you could do it (the first value is always the program file name):
int main(int ac, char **av)
{
int x, y;
if (ac <= 3)
{
x = atoi(av[1]);
y = x; // if there's only one argument, we use it for both x and y
if (ac == 3)
{
y = atoi(av[2]);
}
my_square(&x, &y);
}
return 0;
}

Why does the first column not get printed when I am using gotoxy(x,y)

So I am building a map with borders and filling up with ' * '
Now what I want to do is empty all of the ' * ' and fill them up with blank spaces.
I am not getting the expected output and can't figure out what I am doing wrong, I'd really appreciate if someone could help me.
#include <stdio.h>
#define gotoxy(x,y) printf("\033[%d;%dH", (y), (x))
int height=5;
int width=5;
void fill_blank_spaces()
{
gotoxy(0,0);
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{ if(i!=0 && j!=0 && i!=height-1 && j!=width-1)
printf(" ");
}
printf("\n");
}
}
I expect the output to be:
X---X
| |
| |
| |
X---X
But the displayed output is:
X---X
*|
*|
*|
X---X
int main()
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if ((i == 0 && j == 0) || (i == 0 && j == width - 1) || (j == 0 && i == height - 1) || (j == width - 1 && i == height-1))
printf("X");
else if ((j == 0) || (j == width - 1))
printf("|");
else if (i == height - 1 || i == 0)
printf("-");
else
printf("*") ;
}
printf("\n");
}
fill_blank_spaces();
}
I am new here so excuse my unconventional description.
The top left corner is at ( 1, 1).
The first space on the following lines should go in
( 2, 2), ( 2, 3) and ( 2, 4)
#include <stdio.h>
#define gotoxy(x,y) printf("\033[%d;%dH", (y), (x))
int height=5;
int width=5;
void fill_blank_spaces()
{
for ( int i = 1; i < height - 1; i++)
{
for ( int j = 1; j < width - 1; j++)
{
gotoxy ( j + 1, i + 1);
printf ( " ");
}
}
printf ( "\n");
printf ( "\n");
}
int main ( void)
{
gotoxy ( 1, 1);
for ( int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if ((i == 0 && j == 0) || (i == 0 && j == width - 1) || (j == 0 && i == height - 1) || (j == width - 1 && i == height-1))
printf("X");
else if ((j == 0) || (j == width - 1))
printf("|");
else if (i == height - 1 || i == 0)
printf("-");
else
printf("*") ;
}
printf("\n");
}
fill_blank_spaces();
}
You don't need fill_blanck_spaces, simply replace * by a space :
int main()
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if ((i == 0 && j == 0) || (i == 0 && j == width - 1) || (j == 0 && i == height - 1) || (j == width - 1 && i == height-1))
printf("X");
else if ((j == 0) || (j == width - 1))
printf("|");
else if (i == height - 1 || i == 0)
printf("-");
else
printf(" ") ; //<=== Here
}
printf("\n");
}
return 0;
}

cs50: pset1: credit: Stuck, all cards entered invalid

Been working on this problem set for the past few hours and I thought I was doing pretty well, but when I ran it, doesn't really work as expected.
Kinda stuck at the moment, can anyone offer some insight?
EDIT
Sorry guys, I'll provide a little more insight on the problem because too little info is provided for it in my post. So basically I have to implement the Luhn's algorithm. According to Luhn’s algorithm, you can determine if a credit card number is (syntactically) valid as follows:
Multiply every other digit by 2, starting with the number’s second-to-last digit, and then add those products’ digits together.
Add the sum to the sum of the digits that weren’t multiplied by 2.
If the total’s last digit is 0 (or, put more formally, if the total modulo 10 is congruent to 0), the number is valid!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
printf("type a credit card number: ");
char ccnum[17];
fgets(ccnum, 17, stdin);
int ccnumber[15];
int n = strlen(ccnum);
for (int i = 0; i<16; i++)
{
ccnumber[i] = ccnum[i] -'0';
}
int ccnumber_m[7];
for (int i = 0; i < 16; i+=2)
{
ccnumber_m[i] = ccnumber[i]*2;
}
int sum = 0;
for (int i = 0; i < 8; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
printf("%d\n", sum);
}
for (int i = 1; i < 16; i+=2)
{
sum += ccnumber[i];
}
if (sum%10 == 0)
{
if ( (n == 15) && (ccnumber[0] == 34 || ccnumber[0] == 37))
{
printf("AMEX\n");
}
else if ((n == 16) && (ccnumber[0] == 51 || ccnumber[0] == 52 ||ccnumber[0] == 53 || ccnumber[0] == 54 || ccnumber[0] == 55))
{
printf("MASTERCARD\n");
}
else if ((n == 13 || n == 16) && ccnumber[0] == 4)
{
printf("VISA\n");
}
}
else
{
printf("INVALID\n");
}
}
I've added a printf to my sum variable to see where the program is failing and that's where things seem to be screwing up. Every time I run it, different values of sum appear?!
Thanks in advance.
Okay guys, found the solution. Yes I messed up most of my loops and the array ranges and the conditions were all over the place. Did some tweaks to my code overall and after a few more hours, the code works as expected. Here's the updated code.
Pretty sure the code could be more succinct and could be solved much faster. Will take a look at it tomorrow again in order to brainstorm more ideas and find ways to solve it faster.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
printf("type a credit card number: ");
char ccnum[17];
fgets(ccnum, 17, stdin);
int ccnumber[15];
int n = strlen(ccnum);
int counter = 0;
for (int i = 0; i < n; i++)
{
ccnumber[i] = ccnum[i] -'0';
if (ccnumber[i] >= 0)
{
counter ++;
}
}
int sum = 0;
if (counter == 16)
{
int ccnumber_m[7];
int index = 0;
for (int i = counter - 2; i > -1 ; i-=2, index++)
{
ccnumber_m[index] = ccnumber[i]*2;
}
for (int i = 0; i < 8; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
}
for (int i = 1; i < counter + 1; i+=2)
{
sum += ccnumber[i];
}
}
else if (counter == 15)
{
int ccnumber_m[6];
int index = 0;
for (int i = counter-2; i > 0; i-=2, index++)
{
ccnumber_m[index] = ccnumber[i]*2;
}
for (int i = 0; i < 7; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
}
for (int i = 0; i < counter + 1; i+=2)
{
sum += ccnumber[i];
}
}
else if(counter == 13)
{
int ccnumber_m[5];
int index = 0;
for (int i = counter-2; i > 0; i-=2, index++)
{
ccnumber_m[index] = ccnumber[i]*2;
}
for (int i = 0; i < 6; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
}
for (int i = 0; i < counter + 1; i+=2)
{
sum += ccnumber[i];
}
}
else
{
printf("INVALID\n");
return 0;
}
if (sum%10 == 0)
{
if ((counter == 15) && ((ccnumber[0] == 3 && ccnumber[1] == 4) || (ccnumber[0] == 3 && ccnumber[1] == 7)))
{
printf("AMEX\n");
}
else if ((counter == 16) && ((ccnumber[0] == 5 && ccnumber[1] == 1) || (ccnumber[0] == 5 && ccnumber[1] == 2) || (ccnumber[0] == 5 && ccnumber[1] == 3) || (ccnumber[0] == 5 && ccnumber[1] == 4) || (ccnumber[0] == 5 && ccnumber[1] == 5)))
{
printf("MASTERCARD\n");
}
else if ((counter == 13 || counter == 16) && (ccnumber[0] == 4))
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
else
{
printf("INVALID\n");
return 0;
}
}

C matrix character not appearing printing properly

I am trying to fill a char matrix in C and print it in C but I get only weird characters. I am running this programm on windows, hence the system(cls);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void paint(char tab[10][10], int lignes, int colonnes)
{
system("cls");
for (int i = 0; i < lignes; i++)
{
for (int j = 0; j < colonnes; j++)
{
printf("%c", tab[i][j]);
}
printf("\n");
}
}
void create(char tab[10][10], int lignes, int colonnes)
{
for (int i = 0; i < lignes; i++)
{
for (int j = 0; j < colonnes; j++)
{
tab[i][j] = ' ';
if (i == 0 || i == lignes--)
tab[i][j] = 205;
if (j == 0 || j == colonnes--)
tab[i][j] = 186;
if (i == 0 && j == 0)
tab[i][j] = 201;
if (i == 0 && j == colonnes--)
tab[i][j] = 187;
if (i == lignes-- && j == 0)
tab[i][j] = 200;
if (i == lignes-- && j == colonnes--)
tab[i][j] = 188;
if (i == 50 && j == 50)
tab[i][j] = 248;
}
}
}
int main()
{
char tab[10][10];
create(tab, 10, 10);
paint(tab, 10, 10);
char i;
while(scanf(" %c", &i) != 'q')
{
}
}
I tried changing the output type in printf with %d and %s as shown in other answers here, but %d shows random numbers and %s makes the programm crash, I don't know if it is because of a segfault somewhere.I also tried using simple characters to fill my matrix, not their ascii value.
Don't mind the ineffective scanf , I am still trying to figure out keyboard input without using enter on my own for now.
there were a few problems with your code, like colonnes-- changes the value of colonnes while cheking your if statement
I believe you wanted to draw a rectangle
try this (it's your own code, modified a bit)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char tab[10][10];
void paint(int lignes, int colonnes)
{
system("cls");
for (int i = 0; i < lignes; i++)
{
for (int j = 0; j < colonnes; j++)
{
printf("%c", tab[i][j]);
}
printf("\n");
}
}
void create(int lignes, int colonnes)
{
for (int i = 0; i < lignes; i++)
{
for (int j = 0; j < colonnes; j++)
{
tab[i][j] = ' ';
if (i == 0 || i == lignes-1)
tab[i][j] = 205;
if (j == 0 || j == colonnes-1)
tab[i][j] = 186;
if (i == 0 && j == 0)
tab[i][j] = 201;
if (i == 0 && j == colonnes-1)
tab[i][j] = 187;
if (i == lignes-1 && j == 0)
tab[i][j] = 200;
if (i == lignes-1 && j == colonnes-1)
tab[i][j] = 188;
if (i == 50 && j == 50)
tab[i][j] = 248;
}
}
}
int main()
{
create(10, 10);
paint(10, 10);
}

Trouble with moving tiles in Game of Fifteen

Below is a function in the game of fifteen which should search for the "0" tile and once found, allow adjacent tiles to move into its place. It works for the first few moves but then doesn't allow moves that it should permit when the zero tile is at the top row (it starts on the bottom right). Note below the "0" tile is drawn as an underscore. For example:
8 7 6
5 4 3
2 1 _
Tile to move: 3
8 7 6
5 4 _
2 1 3
Tile to move: 6
8 7 _
5 4 6
2 1 3
Tile to move: 7
Illegal move.
Here is the code:
bool move(int tile)
{
int blankrow;
int blankcol;
for (int i = 0; i < d; i++)
{
for (int j = 0; j < d; j++)
{
if (board[i][j] == 0)
{
blankrow = i;
blankcol = j;
}
}
}
for (int i = 0; i < d; i++)
{
for (int j = 0; j < d; j++)
{
if ((board[i][j] == tile) && ((board[i+1][j] == 0 || board[i-1][j] == 0) &&
(board[i][j+1] == 0 || board[i][j-1] == 0)))
{
int swapped = board[i][j];
board[blankrow][blankcol] = swapped;
board[i][j] = 0;
return true;
}
}
}
return false;
}
Just by looking, I'm pretty sure you need to change:
((board[i+1][j] == 0 || board[i-1][j] == 0) &&
(board[i][j+1] == 0 || board[i][j-1] == 0))
To:
(board[i+1][j] == 0 || board[i-1][j] == 0 ||
board[i][j+1] == 0 || board[i][j-1] == 0)
EDIT: I agree with the user comment below. Better code would look something like:
bool move(int tile)
{
int blankrow, blankcol, tilerow, tilecol;
for (int i = 0; i < d; i++) {
for (int j = 0; j < d; j++) {
if (board[i][j] == 0) {
blankrow = i;
blankcol = j;
}
else if (board[i][j] == tile) {
tilerow = i;
tilecol = j;
}
}
}
if( (blankrow == tilerow && abs(blankcol - tilecol) == 1) ||
(blankcol == tilecol && abs(blankrow - tilerow) == 1) ) {
board[blankrow][blankcol] = board[tilerow][tilecol];
board[tilerow][tilecol] = 0;
return true;
}
return false;
}
You found the blankrow and blankcol. Do the same thing to find the tilerow and tilecol. Then verify either
((blankrow == tilerow) && (abs(blankcol - tilecol) == 1))
or
((blankcol == tilecol) && (abs(blankrow - tilerow) == 1))
Swap if either of those conditions is met. The problem with the existing code is that you can have array accesses out-of-bounds. For example, if i is 0, then board[i-1][j] is an out-of-bounds access.
I think you should change the if statement in the second loop from
if ((board[i][j] == tile) &&
((board[i+1][j] == 0 || board[i-1][j] == 0) &&
(board[i][j+1] == 0 || board[i][j-1] == 0)))
to
if ((board[i][j] == tile) &&
((i+1==blankrow && j==blankcol) ||
(i-1==blankrow && j==blankcol) ||
(i==blankrow && j+1==blankcol) ||
(i==blankrow && j-1==blankcol)))
In the original you are requiring a row offset of one and a column offset of zero and a row offset of zero and a column offset of one simultaneously. Also you're potentially taking a negative index into the array or reading past its end.

Resources