Array Pointer Program to Flip Bits and Add One - c

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

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

Exception Thrown when attempting to compare using pointers

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}

Two-Way Insertion Sort not sorting

This is supposed to be a Two-Way insertion sort, but it's not sorting. I'm also supposed to print out the number of assignments for sorting, but right now I just want it to sort.
A separate output array of size 2n+1 is set aside. Initially x[0] is placed into the middle element of the array n.
Continue inserting elements until you need to insert between a pair of elements in the array.
As before you need to make room for the new element by shifting elements. Unlike before,
you can choose to shift all smaller elements one step to the left or all larger elements one step
to the right since there is additional room on both sides of the array. The choice of which
shift to perform depends on which would require shifting the smallest amount of elements.
I can't find much on the internet about this sort except that no one uses it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printArray(int arr[], int len) {
for (int j = 0; j < len; j++)
printf("%d ", arr[j]);
printf("\n");
}
int main() {
FILE *in;
int size_arr = 0;
char ch;
if ((in = fopen("data_a5.txt", "r")) == NULL) {
printf("Error!");
exit(1);
}
do {
ch = fgetc(in);
if (ch == '\n')
size_arr++;
} while (ch != EOF);
rewind(in);
int arr[size_arr];
int sort_arr[2 * size_arr + 1];
int n = 0;
while (!feof(in)) {
fscanf(in, "%d", &arr[n]);
n++;
}
fclose(in);
for (n = 0; n < 2 * size_arr; n++) {
sort_arr[n] = 0;
}
sort_arr[size_arr] = arr[0];
for (n = 1; n < size_arr; n++) {
int index = size_arr;
if (arr[n] <= sort_arr[size_arr]) {
while (!(arr[n] <= sort_arr[index]) && sort_arr[index] != 0 && index >= 0) {
index--;
}
}
if (arr[n] > sort_arr[size_arr]) {
while (!(arr[n] <= sort_arr[index]) && sort_arr[index] != 0 && index < 2 * size_arr) {
index++;
}
}
if (sort_arr[index] == 0) {
sort_arr[index] = arr[n];
} else {
int next_R, next_L = index;
while (sort_arr[next_R] != 0 && next_R <= 2 * size_arr) {
next_R++;
}
while (sort_arr[next_L] != 0 && next_L >= 0) {
next_L--;
}
int R_move = next_R - index;
int L_move = index - next_L;
if (R_move > L_move) {
while (L_move <= index) {
sort_arr[L_move] = sort_arr[L_move + 1];
L_move++;
}
sort_arr[index] = arr[n];
} else {
while (R_move >= index) {
sort_arr[R_move] = sort_arr[R_move - 1];
R_move--;
}
sort_arr[index] = arr[n];
}
}
}
printArray(arr, size_arr);
return 0;
}
I'm not sure this solves all problems but it is a problem you must fix.
This code
int next_R, next_L = index;
while(sort_arr[next_R] != 0 && next_R <= 2*size_arr)
has undefined behavior as next_R is uninitialized.
Maybe you want:
int next_R = index, next_L = index;
^^^^^
while(sort_arr[next_R] != 0 && next_R <= 2*size_arr)
In any case you have to initialize next_R before using it.
I also find this line strange:
printArray(arr, size_arr);
^^^
Seems you are printing the original array instead of the sorted array.
May be you want:
printArray(sort_arr, size_arr);
^^^^^
There are some problems in your code:
when you scan the file in the first pass, you should count the number of integers instead of the number of characters.
when inserting, your loops are off by one: the tests should read while (L_move < index) and while (R_move >= index)
while (!feof(in)) is always wrong, you should instead write while (fscanf(in, "%d", &arr[n]) == 1) {...
you should probably allocate the arrays arr and sort_arr instead of defining them as VLAs with automatic storage to prevent undefined behavior on large input files.
you should use binary search into the sorted portion, otherwise your algorithm has a basic complexity of O(N2) that dwarfs the small gain obtained from the minimisation of the insertion phase.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
void print_array(const int arr[], int len) {
for (int j = 0; j < len; j++)
printf("%d%c", arr[j], " \n"[j == len - 1]);
}
int main(void) {
FILE *in;
int size_arr, n, start;
int value;
if ((in = fopen("data_a5.txt", "r")) == NULL) {
printf("Cannot open input file %s\n", "data_a5.txt");
exit(1);
}
for (size_arr = 0; fscanf(in, "%d", &value) == 1; size_arr++)
continue;
rewind(in);
int *arr = calloc(2 * size_arr + 1, sizeof(*arr));
if (arr == NULL) {
printf("Cannot allocate memory for %d entries\n", size_arr);
exit(1);
}
start = size_arr;
for (n = 0; n < size_arr && fscanf(in, "%d", &value) == 1; n++) {
/* insert value into the sorted array */
int a, b;
for (a = start, b = start + n; a < b;) {
int mid = a + (b - a) / 2;
if (arr[mid] < value) {
a = mid + 1;
} else {
b = mid;
}
}
/* insert value at offset b */
if (b - start < start + n - b) {
/* shift left portion to the left */
for (int i = start--; i < b; i++) {
arr[i - 1] = arr[i];
}
b--;
} else {
/* shift right portion to the right */
for (int i = start + n + 1; --i > b;) {
arr[i] = arr[i - 1];
}
}
arr[b] = value;
}
fclose(in);
print_array(arr + start, n);
free(arr);
return 0;
}
like this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printArray(int arr[], int len){
while(len--)
printf("%d ", *arr++);
printf("\n");
}
int main(void){
int size_arr = 10;
int arr[size_arr];
int sort_arr[2 * size_arr + 1];
for(int i = 0; i < size_arr; ++i)
arr[i] = -50 + rand() % (100 + 1);
puts("before:");
printArray(arr, size_arr);
int left, right;
sort_arr[left = right = size_arr] = arr[0];
for (int n = 1; n < size_arr; ++n){
int v = arr[n];
if(v <= sort_arr[left]){
sort_arr[--left] = v;
} else if(v >= sort_arr[right]){
sort_arr[++right] = v;
} else {
int L = left, R = right, M, MV;
while(L <= R){
M = L + (R-L)/2;
MV = sort_arr[M];
if(MV < v)
L = M + 1;
else if(v < MV)
R = M - 1;
else
break;
}
//M: insert position
enum { LEFT, RIGHT } CHOICE;
if(v == MV){
int ML = M, MR = M;
while(sort_arr[ML-1] == sort_arr[ML])
--ML;
while(sort_arr[MR] == sort_arr[MR+1])
++MR;
if( ML-left >= right-MR){
M = MR+1;
CHOICE = RIGHT;
} else {
M = ML;
CHOICE = LEFT;
}
} else if(v > MV){
++M;
CHOICE = M-left+1 > right-M;// ? RIGHT : LEFT;
} else {
CHOICE = M-left-1 > right-M;// ? RIGHT : LEFT;
}
if(CHOICE == RIGHT){
memmove(sort_arr + M+1, sort_arr + M, (right-M+1)*sizeof(v));
sort_arr[M] = v;
++right;
} else {
memmove(sort_arr + left-1, sort_arr + left, (M-left)*sizeof(v));
sort_arr[M-1] = v;
--left;
}
}
}
puts("after:");
printArray(sort_arr + left, size_arr);
return 0;
}

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

Resources