C programming / what is the difference between these two codes [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
What is the difference between these two codes? I think it's same code.
It can't operate both of codeup and Visual Studio.
codeup.kr 1505 problem
The problem for array
when you put number it
it makes num*num array
For example, given num = 3, it creates:
1 2 3
8 9 4
7 6 5
Code 1:
#include<stdio.h>
#include<string.h>
int main()
{
int tile[52][52];
int x, y;
int num;
int start = 1;
int check = 1, complete = 1;
int i;
scanf("%d", &num);
memset(tile, 0, 4 * 52 * 52);
tile[0][1] = 10;
tile[1][num + 1] = 10;
tile[num + 1][num + 1] = 10;
tile[num + 1][0] = 10;
x = 1; y = 1;
for (i = 0; i <= 3000; i++)
{
switch (check)
{
case 1:
{
if (tile[x][y + 1] != 0)
{
check += 1;
break;
}
tile[x][y++] = start;
start++;
complete++;
break;
}
case 2:
{
if (tile[x + 1][y] != 0)
{
check += 1;
break;
}
tile[x++][y] = start;
start++;
complete++;
break;
}
case 3:
{
if (tile[x][y - 1] != 0)
{
check += 1;
break;
}
tile[x][y--] = start;
start++;
complete++;
break;
}
case 4:
{
if (tile[x - 1][y] != 0)
{
check = 1;
break;
}
tile[x--][y] = start;
start++;
complete++;
break;
}
}
if (complete == num*num)
{
break;
}
}
if (num % 2 == 0)
{
tile[x][y] = start;
}
else
{
tile[x][y++] = start;
}
for (x = 1;x <= num; x++)
{
for (y = 1; y <= num; y++)
{
printf("%d ", tile[x][y]);
}
printf("\n");
}
}
This code operates in Visual Studio.
#include<stdio.h>
int main()
{
int tile[52][52];
int x, y;
int num;
int start = 1;
int check = 1, complete = 1;
int i;
scanf("%d", &num);
for (x = 0;x <= num; x++)
{
for (y = 0; y <= num; y++)
{
tile[x][y] = 0;
}
}
tile[0][1] = 10;
tile[1][num+1] = 10;
tile[num + 1][num + 1] = 10;
tile[num + 1][0] = 10;
x = 1; y = 1;
for (i = 0; i <= 3000; i++)
{
switch (check)
{
case 1:
{
if (tile[x][y + 1] != 0)
{
check += 1;
break;
}
tile[x][y++] = start;
start++;
complete++;
break;
}
case 2:
{
if (tile[x + 1][y] != 0)
{
check += 1;
break;
}
tile[x++][y] = start;
start++;
complete++;
break;
}
case 3:
{
if (tile[x][y - 1] != 0)
{
check += 1;
break;
}
tile[x][y--] = start;
start++;
complete++;
break;
}
case 4:
{
if (tile[x - 1][y] != 0)
{
check = 1;
break;
}
tile[x--][y] = start;
start++;
complete++;
break;
}
}
if (complete == num*num)
{
break;
}
}
if (num % 2 == 0)
{
tile[x][y] = start;
}
else
{
tile[x][y++] = start;
}
for (x = 1;x <= num; x++)
{
for (y = 1; y <= num; y++)
{
printf("%d ", tile[x][y]);
}
printf("\n");
}
}

The difference:
$ diff -w one.c two.c2,3d1
< #include<string.h>
<
14,15c12,16
< memset(tile, 0, 4 * 52 * 52);
<
---
> for (x = 0; x <= num; x++) {
> for (y = 0; y <= num; y++) {
> tile[x][y] = 0;
> }
> }
95a97
>
so, the first one uses memset to set all entries of tile to 0 (zero) and the second one uses a loop to set only the entries of tile to zero that are used, the content of the rest of the cells is undefined, could be everything. You can look for some places where x and/or y are outside of 0 <= x <= num < 52 in your code, or step through with a debugger, or use printf()s to find the exact places.
If you do not want to use memset() or are not able too: just change the loop to zero every cell out:
for (x = 0; x < 52; x++) {
for (y = 0; y < 52; y++) {
tile[x][y] = 0;
}
}

Related

Why does writing this program output me weird strings?

I am trying to code minesweeper in C. I started out with assigning the values to a 2D array then print it. I tried everything but it didn't work.
This happens in my sample output:
The code is:
#include <stdio.h>
#include <stdlib.h>
struct Tile {
unsigned char isMine : 1;
char status;
};
int main() {
struct Tile arr[9][9];
unsigned char i;
unsigned char c;
unsigned char count = 10;
srand((unsigned)time(0));
for (i = 0; i < 9; i++) {
for (c = 0; i < 9; i++) {
if(rand() % 81 + 1 < count && arr[i][c].isMine == 0 && count > 0) {
arr[i][c].isMine = 1;
arr[i][c].status = 'X';
count--;
} else if (arr[i][c].isMine == 0) {
arr[i][c].status = '.';
}
}
if (count == 0) {
break;
} else {
continue;
}
}
for (i = 0; i < 9; i++) {
for (c = 0; c < 9; c++) {
printf("%c", arr[i][c].status);
}
printf("\n");
}
return 0;
}
Please help.
You never visit any fields in your loops except the 1st column due to incorrect loop header:
for (i = 0; i < 9; i++) {
for (c = 0; i < 9; i++) {
if(rand() % 81 + 1 < count && arr[i][c].isMine == 0 && count > 0) {
arr[i][c].isMine = 1;
arr[i][c].status = 'X';
count--;
} else if (arr[i][c].isMine == 0) {
arr[i][c].status = '.';
}
}
if (count == 0) {
break;
} else {
continue;
}
}
This will leave all other fields uninitialized and when you try to print it, strange things may appear.
Also as you only visit each field once (or at least that seems to be your intention), there is no need to check isMine at all. If you initialize properly, it must be 0 anyway.
Which of course requires that you intitialize properly as already mentioned in David's answer.
The condition can be reduced a bit more as the first part (..+1<count) already implies that count>0. No need to check again.
Finally, continue as last instruction of a loop is not really useful.
Your code could look like this:
struct Tile arr[9][9] = {{0}};;
...
for (i = 0; i < 9; i++) {
for (c = 0; c < 9; c++) {
if(rand() % 81 + 1 < count) {
arr[i][c].isMine = 1;
arr[i][c].status = 'X';
count--;
} else {
arr[i][c].status = '.';
}
}
if (count == 0) {
break;
}
}
Initialize the array:
struct Tile arr[9][9] = {{0}};
otherwise you read an uninitialized value (leading to undefined behaviour) in:
} else if (arr[i][c].isMine == 0) {
arr[i][c].status = '.';
}

My program gives the correct output in windows(gcc) but in Linux(gcc) it leads to segmentation fault

This program is to find the epsilon closure of all states of an NFA. I have used the stack to get this done.The program gives the right output when I compiled it using gcc and ran it Windows 10(Command Prompt). But when I compiled with the same compiler and ran it in Linux it results in segmentation fault. I have used any dynamic memory allocation for that matter.
I tried to debug using gdb but not able to find the problem. Detected a segmentation fault after a printf("\n") when displaying the transitions matrix.
It would be very helpful for someone could find the fault. Thanks in advance.
The input is read from a file : nfa.txt.
//states
q0 q1 q2
//input_symbols
0 1
//start_state
q0
//final_state
q2
//transitions of the form : intial_state input final_state
q0 0 q0
q0 e q1
q1 1 q1
q1 e q2
q2 2 q2
The output is as follows:
232 is to represent null transition(Φ) and -1 for ε.
States:
q0
q1
q2
Transitions read
232 0 1 2 -1
0 0 232 232 1
1 232 1 232 2
2 232 232 2 232
e-closure(0) : 0 1 2
e-closure(1) : 1 2
e-closure(2) : 2
Please bear with me because it's a fairly long program.
#include <stdio.h>
#include <string.h> //REMEMBER ME WHILE I'M GONE
#include <errno.h>
#include <stdlib.h>
FILE *file;
int numberOfStates = 0;
int flag = 0;
int states[20];
int j = 0;
int i = 0;
int k = 0;
char a[20];
int transitions[4][5];
int visited[10];
int MAXSIZE = 8;
int stack[8];
int top = -1;
int isempty()
{
if(top == -1)
return 1;
else
return 0;
}
int isfull()
{
if(top == MAXSIZE)
return 1;
else
return 0;
}
int pop()
{
int data;
if(!isempty()) {
data = stack[top];
top = top - 1;
return data;
}
else
printf("Could not retrieve data, Stack is empty.\n");
}
int push(int data) {
if(!isfull()) {
top = top + 1;
stack[top] = data;
}
else
printf("Could not insert data, Stack is full.\n");
}
int IsVisited(int edge)
{
for(int i = 0; i < 10; i++)
if(visited[edge] == 1)
return 1;
return 0;
}
void epsilon_closure(int state)
{
int e_closure[10];
for(int i = 0; i < 10; i++ )
{ e_closure[i] = -1;
visited[i] = 0;
}
push(state);
visited[state] = 1;
while(top != -1)
{
int u = pop();
j = 1;
while(j < 5)
{
//if there is an epsilon transition from the state 'u' to 'v'
if(transitions[j][0] == u && transitions[j][4] != 232) //ASCII of Φ = 232
{
if(! IsVisited(transitions[j][4]))
{
visited[transitions[j][4]] = 1;
push(transitions[j][4]);
}
}
j++;
}
}
j = 0;
for(int edge = 0; edge < 10; edge++)
{
if(visited[edge] == 1)
e_closure[j++] = edge;
}
printf("e-closure(%d) : ",state);
for (i = 0; e_closure[i] != -1; ++i)
printf("%d ", e_closure[i]);
printf("\n");
}
int main()
{
file = fopen("nfa.txt","r");
if (file == NULL) {
perror("fopen");
return -1;
}
//Reading the states
while(!feof(file))
{
fscanf(file,"%s",a);
if(strcmp("//states",a) == 0)
flag = 1;
else if(strcmp("//input_symbols",a) == 0)
break;
if (flag == 1 && a[0] != '/')
{
states[i++] = a[1] - '0';
}
numberOfStates = i;
}
//Display the states of the e-NFA
printf("\nStates : \n");
for(i = 0; i < numberOfStates; i++ )
{
printf("q%d\n",states[i]);
}
i = 1;
flag = 0;
//Reading the transition table
for(int i = 0; i < 4; i++){
for(int j = 0; j < 5; j++)
{
transitions[i][j] = 232;
}
}
while(!feof(file))
{
fgets(a,100,file);
if(a[0] == '/')
{
flag = 1;
}
if(flag == 1 && a[0] != '/')
{
j = 0;
//found a way to store the transition table in a matrix
if(a[3] == 'e')
transitions[(a[1] - '0') + 1][4] = a[6] - '0';
else
transitions[(a[1] - '0') + 1][(a[3] - '0') + 1] = a[6] - '0';
if(a[3] != 'e')
transitions[0][a[3] - '0' + 1] = a[3] - '0'; //input
else
transitions[0][4] = -1; // epsilon input
transitions[(a[1] - '0') + 1][0] = a[1] - '0'; //initial state
}
}
printf("\nTransitions read\n");
for(int i = 0; i < 4; i++){
for(int j = 0; j < 5; j++)
{
printf("%d\t",transitions[i][j]);
}
printf("\n"); //detected segmentation fault here
}
//Calling e-closure for all the states
for(k = 0; k < numberOfStates; k++)
{
epsilon_closure(states[k]);
}
return 0;
}
There is a bug here:
int push(int data) {
if(!isfull()) {
top = top + 1;
stack[top] = data;
}
else
printf("Could not insert data, Stack is full.\n");
}
If top == MAXSIZE-1, isfull() will return false, then you increment top to MAXSIZE and assign stack[MAXSIZE] what is out of bounds and invokes UB. Not having checked the complete source code, I could imagine that incrementing top after assigning would be correct or you have to change isfull() to return true if top >= MAXSIZE-1

Cannot print returned value in C

I ran compile this:
char get_credit_card_status(long long credit_card_number, char Luhn_validity)//, char credit_card_status)
{
char credit_card_status = 0;
if (((credit_card_number < 350000000000000) && (340000000000000 <=credit_card_number)) && (Luhn_validity=1))
{
credit_card_status = 1;
printf("1 test\n");
}
else if ((5100000000000000<= credit_card_number) && (credit_card_number < 5500000000000000) && Luhn_validity)
{
credit_card_status = 2;
printf("2 test\n");
}
else if ((((4000000000000<= credit_card_number)&&(credit_card_number<5000000000000)) || ((4000000000000000<=credit_card_number)&&(credit_card_number<5000000000000000))) && Luhn_validity)
{
credit_card_status= 3;
printf("3 test\n");
}
return credit_card_status;
}
int length_ccn(long long credit_card_number)
{
int length = 0;
while (credit_card_number > 0)
{
length++;
credit_card_number /= 10 ;
}
return length;
}
char Luhn_check(long long credit_card_number)
{
int total_even_numbers = 0;
int total_odd_numbers = 0;
int even_number = 0;
int odd_number = 0;
int Luhn_sum = 0;
char Luhn_validity = 0;
long long check_digit_basis = credit_card_number;
for(int i =1 ; check_digit_basis > 0 ; i++)
{
if ((i % 2) > 0)
{
odd_number = (check_digit_basis % 10);
total_odd_numbers = total_odd_numbers + odd_number;
}
else
{
even_number = (check_digit_basis % 10);
if(even_number >= 5)
{
total_even_numbers = total_even_numbers + ((( 2 * even_number) % 10) + 1 );
}
else
{
total_even_numbers = total_even_numbers + (2 * even_number);
}
}
check_digit_basis = (check_digit_basis / 10);
}
Luhn_sum = total_even_numbers + total_odd_numbers;
if ((Luhn_sum % 10 ) == 0 )
{
Luhn_validity = 1;
}
else
{
Luhn_validity = 0;
printf("%c for Luhn_validity\n", Luhn_validity);
}
printf("%d for Luhn_validity\n", Luhn_validity);
return Luhn_validity;
}
int main(void)
{
printf("Provide your credit card number:\n");
long long credit_card_number = get_long_long();
int length = length_ccn(credit_card_number);
printf("%i for length\n", length);
char Luhn_validity = Luhn_check(credit_card_number);
printf("%c returned from line 119\n", Luhn_validity);
char credit_card_status;
credit_card_status = get_credit_card_status(credit_card_number, Luhn_validity);
switch (credit_card_status)
{
case 1:
printf("American Express\n");
break;
case 2:
printf("MasterCard\n");
break;
case 3:
printf("Visa\n");
break;
default:
printf("INVALID\n");
}
}
I got:
15 for length
1 for Luhn_validity
returned from line 119
The value of Length is returned to the main function while Luhn_validity isn't. Why?
I cannot make another post because someone posted an incomplete answer only answering to what I already began to implement (see the post before its edits and you'll see that the boolean problem was being corrected and wasn't in the post's title).
credit_card_status = credit_card_status(credit_card_number)
You try to use the same name, credit_card_status, for two different things. If the function is called credit_card_status don't store it's return value in credit_card_status, because that's the function and not a variable. This leads to the error that credit_card_status is not assignable.
error: comparison of constant 350000000000000 with boolean expression is always true
There is no "twoway" comparison a <= x < b in C, you have to use two separate comparisons: a <= x && x < b.

testcase not running in c program

iam new to c program and facing difficulty in debugging programs.In the below code test case 2 is not running.I have found that the error is in reading interger n in the second test case.someone please hep me with this issue.Also please recommend me with some tools that can be ued for debugging c programs using terminal.Thanks for help
#include <stdio.h>
#include <stdlib.h>
int read(){
int r = 0;
char c = getchar_unlocked();
while(c >= '0' && c <= '9'){
r = r*10 + c - 48 ;
c = getchar_unlocked();
}
return r;
}
void main(){
int t = 0;
t = read();
int rr = 0;
for(rr = 0;rr < t;rr++){
int i,n = 0;
n = read();
int *p = (int *)calloc(n,sizeof(int));
for(i = 0;i < n;++i){
*(p+i) = getchar_unlocked() - 48;
}
int no,nz = 0;
for(i = 0;i < n;++i){
if(*(p+i) == 0){nz += 1;}
if(*(p+i) == 1){no += 1;}
}
int k = 0;
if(((no)%2 == 0) && ((nz)%2) == 0){
k = -1;
}
if(((no)%2 == 0) && ((nz)%2) == 1){
k = 0;
}
if(((no)%2 == 1) && ((nz)%2) == 0){
k = 1;
}
if(((no)%2 == 1) && ((nz)%2) == 1){
k = 1;
}
int result = 0;printf("%d\n",5556);
if(k == 1){
for(i = 0;i < n;++i){
if(*(p+i) == 1){
result = i+1 ;
break;
}
}
}
if(k == 0){
for(i = 0;i < n;++i){
if(*(p+i) == 0){
result = i+1 ;
break;
}
}
}
printf("%d\n",result);
}
}
Your strategy to read an integer is flawed. You don't have the logic to skip whitespaces. I would change the function name to read_int and change its implementation to
int read(){
int n;
if ( scanf("%d", &n) != 1 )
{
// Deal with the error
}
return n;
}
Also, change
*(p+i) = getchar_unlocked() - 48;
to
*(p+i) = read_int();
or a more intuitive version:
p[i] = read_int();
With those changes, I am able to read and process the numbers. But I still get the wrong output. I'll let you figure the logic error in your code.
Additional Comments
main is expected to return an int. If your compiler didn't complain about that, it's time to up the warning level. I use -Wall by default.
When you are in the process of debugging your code, it's always good to test the code that reads the input to make sure that there is no error in reading the input.
Here's what I did to your code:
#include <stdio.h>
#include <stdlib.h>
int read_int(){
int n;
if ( scanf("%d", &n) != 1 )
{
// Deal with the error.
}
return n;
}
int main(){
int t = 0;
int rr = 0;
t = read_int();
printf("t = %d\n", t);
for(rr = 0;rr < t;rr++){
int i,n = 0;
n = read_int();
printf("n = %d\n", n);
int *p = (int *)calloc(n,sizeof(int));
for(i = 0;i < n;++i){
p[i] = read_int();
printf("p[%d] = %d\n", i, p[i]);
}
int no,nz = 0;
for(i = 0;i < n;++i){
if(*(p+i) == 0){nz += 1;}
if(*(p+i) == 1){no += 1;}
}
int k = 0;
if(((no)%2 == 0) && ((nz)%2) == 0){
k = -1;
}
if(((no)%2 == 0) && ((nz)%2) == 1){
k = 0;
}
if(((no)%2 == 1) && ((nz)%2) == 0){
k = 1;
}
if(((no)%2 == 1) && ((nz)%2) == 1){
k = 1;
}
int result = 0;
// printf("%d\n",5556);
if(k == 1){
for(i = 0;i < n;++i){
if(*(p+i) == 1){
result = i+1 ;
break;
}
}
}
if(k == 0){
for(i = 0;i < n;++i){
if(*(p+i) == 0){
result = i+1 ;
break;
}
}
}
printf("%d\n",result);
}
return 0;
}

Segfault on disease simulator

I am trying to program a disease simulator in C. For some reason after around 20-25 iterations of the while(1) loop, it segfaults. It is completely random. I have been trying to fix this problem for several hours, so any help would be much appreciated.
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
typedef struct space {
int type;
int x, y;
} space_t;
space_t space[40][40];
int main(){
bool infected = false;
int i = 0;
int x = 0;
int y = 0;
srand(time(NULL));
while(i < 1600){
space[x][y].x = x;
space[x][y].y = y;
if(rand() % 9 == 0 && !infected){
space[x][y].type = 1;
infected = true;
}
if(rand() % 20 == 8){
space[x][y].type = 2;
}
x++;
i++;
if(x == 40){
x = 0;
y++;
}
}
system("clear");
int count;
int inf = 0;
while(1){
x = 0;
y = 0;
i = 0;
while(i < 1600){
if(space[x][y].type == 1){
inf++;
}
if(space[x][y].type == 1 && rand() % 9 > 4){
if(rand() % 9 > 4){
space[x+(rand() % 3)][y].type = 1;
} else {
space[x+(-(rand() % 3))][y].type = 1;
}
} else if(space[x][y].type == 1 && rand() & 9 > 4){
if(rand() % 9 > 4){
space[x][y+(rand() % 3)].type = 1;
} else {
space[x][y+(-(rand() % 3))].type = 1;
}
}
if(space[x][y].type == 1){
printf("[I]");
} else if(space[x][y].type == 2){
printf("[D]");
} else printf("[ ]");
x++;
i++;
if(x == 40){
printf("\n");
x = 0;
y++;
}
}
count++;
printf("%d\n", count);
printf("%d\n", inf);
sleep(1);
system("clear");
}
return 0;
}
Code generates random offsets for an index but does not insure in proper range.
if(space[x][y].type == 1 && rand() % 9 > 4){
if(rand() % 9 > 4){
// Nothing forces `x+(rand() % 3)` in legal index range.
space[x+(rand() % 3)][y].type = 1;
} else {
space[x+(-(rand() % 3))][y].type = 1;
}
}
Instead
if(space[x][y].type == 1 && rand() % 9 > 4) {
int r = rand();
if(r % 9 > 4) {
int offset = x + r%3;
if (offset < 40) space[offset][y].type = 1;
} else {
int offset = x - r%3;
if (offset >= 0) space[offset][y].type = 1;
}
}
... // similar change for next block
Note: later on code, certainly rand() & 9 should be rand() % 9 (% not &).

Resources