I am trying to make a loop that makes a pointer point to different elements in an array (Sorting in descending order) and I can't seem to get the comparing correctly since I always get an exception thrown. I also have a loop to print all the pointer's elements to test if the loop worked correctly. Never really used pointers before, but I tried to format them the same way I've seen on other websites when studying pointers. This is the part of code I am talking about:
//What I have included
#define _CRT_SECURE_NO_WARNINGS
#define MAX 5
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
//Variables related to the loops
int nums[MAX], *ptrd[MAX];
//Loops in question (Assume nums[MAX] = {1, 2, 3, 4, 5})
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
{
if (*ptrd[i] < nums[j] && nums[j] <= *ptrd[i - 1])
{
if (i > 0)
{
if (ptrd[i] == ptrd[i - 1])
continue;
}
ptrd[i] = &nums[i];
}
}
}
for (int i = 0; i < MAX; i++)
{
printf("\n%d", *ptrd[i]);
}
Current full code so far (note the code in question here is different):
#define _CRT_SECURE_NO_WARNINGS
#define MAX 5
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
//Variables
char input[20];
int nums[MAX], *ptrd[MAX], *ptra[MAX];
bool isValid;
//Methods
bool checkValidity();
void convertChars();
void resetInput();
int main()
{
printf("Please enter 5 numbers (Separate each by spaces): ");
input:
resetInput();
scanf(" %[^\n]%*c", &input);
isValid = checkValidity();
if (isValid == false)
{
printf("Invalid input. Retry: ");
goto input;
}
convertChars();
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
{
if (*ptrd[i] < nums[j])
{
if (i > 0)
{
if (ptrd[i] == ptrd[i - 1])
continue;
if (nums[j] <= *ptrd[i - 1])
ptrd[i] = &nums[i];
}
else
ptrd[i] = &nums[i];
}
}
}
for (int i = 0; i < MAX; i++)
{
printf("\n%d", (*ptrd)[i]);
}
getchar();
return 0;
}
bool checkValidity()
{
bool multNum = false;
int chars = 0;
for (int i = 0; i < 20; i++)
{
if (!isdigit(input[i]))
{
if (input[i] == ' ' && multNum == true || input[i] == NULL && multNum == true)
chars += 1;
if (input[i] != ' ' && input[i] != NULL)
{
printf("\nIncorrect characters\n");
return false;
}
if (input[i] == ' ' && multNum == false)
{
printf("\nToo many spaces at at once\n");
return false;
}
if (input[i] == ' ' && multNum == true || input[i] == NULL && multNum == true)
multNum = false;
}
else if (isdigit(input[i]))
{
multNum = true;
}
}
if (chars != 5)
{
printf("\nIncorrect amount of nums (%d)\n", chars);
return false;
}
else
return true;
}
void convertChars()
{
int placeHolder, nums_ = 0, done = 0;
for (int i = 0; i < 20 && done < 5; i++)
{
if (isdigit(input[i]))
{
placeHolder = input[i] - '0';
nums_ = (nums_ * 10) + placeHolder;
}
else
{
nums[done] = nums_;
nums_ = 0;
done += 1;
}
}
}
void resetInput()
{
for (int i = 0; i < 20; i++)
{
input[i] = NULL;
}
}
You didn't initialize *ptrd[MAX], which results in an undefined behavior. Run your code with gdb, and it crashes with following output:
(gdb) run
Starting program: /home/pringles/Desktop/a.out
Please enter 5 numbers (Separate each by spaces): 3 2 1 5 6
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400719 in main () at test.c:37
37 if (*ptrd[i] < nums[j])
By printing the elements in ptrd, you can see all the elements point to 0x0:
(gdb) print ptrd
$1 = {0x0, 0x0, 0x0, 0x0, 0x0}
Related
I'm having some problem with saveing the vaule of the longest fence.
I tried this:
int longestFence(char input [], int size)
{
int i , max = 0, count = 0;
for(i = 0; i < size ; i++)
{
if(input[i] == '|' && input[i] == '-')
{
count = 1;
}
if(input[i] != input[i + 1])
{
count++ - 1;
}
}
return count;
}
In practice, to detect is the fence is still valid, you just have to check if the current symbol is different or not than the previous one.
You also have to check if the current count is longer or not than the previous longest one.
Besides, I modified the random string generator: the current one is rather inefficient.
In addition, the string generated is not terminated by the Null character. I also modified it.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
int longestFence (char input[], int size) {
if (size == 0) return 0;
int max_count = 0;
int count = 1;
for (int i = 1; i < size; ++i) {
if (input[i] != input[i-1]) {
count++;
} else {
if (count > max_count) max_count = count;
count = 1;
}
}
if (count > max_count) max_count = count;
return max_count;
}
int main() {
char string[MAX+1];
char symbols[] = {'|', '-'};
srand (time(NULL));
int length = rand() % (MAX+1);
for (int i = 0; i < length; ++i) {
int val = (rand() / 16) % 2;
string[i] = symbols[val];
}
string[length] = '\0';
printf ("String is: %s\n", string);
printf ("Longest fence = %d\n", longestFence (string, length));
return 0;
}
I have this code below (whole code after this section). I am wanting to include more than one casse for this section of the code:
for(i = 0; i < length; i++)
{
if(numberArray[i] == 1)
{
casse = 2;
}
if(numberArray[i] == 2)
{
casse = 3;
}
if(numberArray[i] == 1 || numberArray[i] == 2)
{
casse = 4;
}
}
So far, the above prints '4' when the value '8213' is entered. This is expected since for each round of for loop the 'casse' variable gets updated, by the time it runs the last integer in the array, the value for 'casse' has undergone many replacements and the end result is the last replacement of '4'.
The objective of the code is to determine which cases (casse) have
been met. There can be more than one case (casse) being met, but as it
stands now, it only has room for one case.
#include <stdio.h>
#include <math.h>
int main(void) {
int odo, value, casse;
int i;
printf("please enter a value for the odometer:\n");
scanf("%d", &odo);
value = odo;
casse = 0;
int length = floor(log10(abs(odo))) + 1;
/* count number of digits */
int c = 0; /* digit position */
int n = value;
while (n != 0)
{
n /= 10;
c++;
}
int numberArray[c];
c = 0;
n = value;
/* extract each digit */
while (n != 0)
{
numberArray[c] = n % 10;
n /= 10;
c++;
}
for(i = 0; i < length; i++)
{
printf("%d, ", numberArray[i]);
}
for(i = 0; i < length; i++)
{
if(numberArray[i] == 1)
{
casse = 2;
}
if(numberArray[i] == 2)
{
casse = 3;
}
if(numberArray[i] == 1 || numberArray[i] == 2)
{
casse = 4;
}
}
printf("\n%d\n", casse);
return 0;
}
Output:
please enter a value for the odometer:
8213
3, 1, 2, 8,
4
Expected output:
please enter a value for the odometer:
8213
3, 1, 2, 8,
Not only '4', but also '3', '2'.
Rather than a single variable that keeps track of the last case, you want an array which keeps track of all cases. For a small number of cases, the array can be a fixed size, with the index as case number and the value in the array as the number of times that case was triggered:
int cases[5] = {0};
for(i = 0; i < length; i++)
{
if(numberArray[i] == 1)
{
cases[2]++;
}
if(numberArray[i] == 2)
{
cases[3]++;
}
if(numberArray[i] == 1 || numberArray[i] == 2)
{
cases[4]++;
}
}
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 = '.';
}
I am trying to write a program that will take an arbitrary number and flip the bits and add one, and I have written the code, but I keep getting a segmentation fault (core dumped) error. Could someone look at my code and see why that error is occurring. I have attached my code below and the input and output I would like to receive.
#include "stdio.h"
#include "malloc.h" //Needed for malloc, realloc, and free
#define GROW_BY 2
#define MAX_BITS 32
int add_one(int in_array[], int num){
for (int i = 0; in_array[i] != NULL; i++) {
int add_one = in_array[num - i] + 1;
}
return add_one;
}
int main() {
//Declaration and Initialization of Variables
int* array = NULL;
int bit = getchar();
int count = 0;
while (bit != '\n') {
bit = bit - '0';
*array = &bit;
array = (int*)malloc((strlen(bit) + 1) * sizeof(int));
if (array == NULL) {
printf("An error has occurred and the program will now $
return 1;
}
bit = getchar();
}
for (int j = count - 1; j >= 1; j--) {
if (array[j] == '1') {
array = (int*)realloc(array, GROW_BY * sizeof(int));
if (array == NULL) {
printf("An error has occurred and the program w$
}
}
else if (array[j] == '0' ) {
array = (int*)realloc(array, GROW_BY * sizeof(int));
if (array == NULL) {
printf("An error has occurred and the program w$
return 1;
}
}
}
add_one(array, bit);
for (int j = count - 1; j >= 1; j--) {
if (array[j] == '1' && add_one == 1) {
array[j] = '0';
}
else if (array[j] == '0' && add_one == 1) {
array[j] = '1';
int add_one = 0;
}
else {
array[j] = array[j];
}
}
printf("%ls/n", array);
free(array);
return 0;
}
Input: 101011110
Output: 010100010
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