Printing a multi dimensional array - c

I've written a little thing which asks the user for some input (rows and cols), which should then set everything in an array to a dot (".") and print it out, but this crashes my application.
void main()
{
int i,j, m, n;
printf("The number of lines (m): ");
scanf("%d", m );
printf("\nThe number of columns (n): ");
scanf("%d", n);
//create my array
char mineGrid[n][m];
//set all fields in to safe (.)
for (j = 0; j <= n; j++)
{
for (i = 0; i <= m; i++)
{
mineGrid[j][i] = ".";
}
}
//print a grid of dots
for (j = 0; j <= n; j++)
{
for (i = 0; i <= m; i++)
{
printf("%s", mineGrid[j][i]);
}
}
}
Any idea why this is crashing?

On cause of major trouble here is that you have a lot of loop that look like
for (j = 0; j <= n; j++)
/* ^ */
/* | */
/* Look! */
which will run j from 0 to n, but you have declared your array as
char mineGrid[n][m];
which means that space has been allocated for rows numbered 0 to n-1.
All you index loops are wrong in that way. The idomatic way to write those loops is
for (j = 0; j < n; ++j)
where I have fixed the range and also changed the increment from post- to pre- which is an old micro-optimization that generally does not make any difference in c these days (because compilers are smart enough to fix it), but can if you switch to c++ and use a non-trivial class in that way. So I keep it in my list of little things to "fix".

That's because you're putting a string in the array instead of char.
do it like this:
void main()
{
int i,j, m, n;
m = 5;
n = 6;
//create my array
char mineGrid[n][m];
//set all fields in to safe (.)
for (j = 0; j <= n; j++)
{
for (i = 0; i <= m; i++)
{
mineGrid[j][i] = '.';
}
}
//print a grid of dots
for (j = 0; j <= n; j++)
{
for (i = 0; i <= m; i++)
{
printf("%c", mineGrid[j][i]);
}
printf("\n");
}
}

you created n X m elements but used n+1 X m+1 elements in array. use like bellow
a
for (j = 0; j < n; j++)
{
for (i = 0; i < m; i++)
{
mineGrid[j][i] = '.';
}
}

That's because for an array of size N, the valid array indexes 0 to N-1. But you are accessing N th element which is not a valid array index and accessing it invokes undefined behavior.
for (j = 0; j <= n; j++)
{
for (i = 0; i <= m; i++) // Array out of bounds in either condition check
With that said, you have issues with your input as well.
scanf("%d", m ); // Missing & operator before m.

Related

Removing duplicates in a C array

I am writing a program which determines the intersection of 2 integer arrays (size of 10 elements). I think I got every other parts covered except for sorting out duplicates. Does anyone know a way of checking duplicates without making a function or using an external C library?
#include <stdio.h>
#define SIZE 10
int main(void){
//Initialization
int array1[SIZE];
for (int i = 0; i < SIZE; i++)
{
printf("Input integer %d of set A: ", i + 1);
scanf("%d", &array1[i]);
}
int array2[SIZE];
for (int i = 0; i < SIZE; i++)
{
printf("Input integer %d of set B: ", i + 1);
scanf("%d", &array2[i]);
}
int intersection[SIZE];
for (int i = 0; i < SIZE; i++)
{
intersection[i] = '\0';
}
//Intersection check
for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
if (array1[i] == array2[j])
{
intersection[i] = array1[i];
break;
}
}
}
//duplicate check
int count = SIZE;
for (int i = 0; i < count; i++)
{
for (int j = i + 1; j < count; j++)
{
if (intersection[i] == intersection[j])
{
for (int k = j; j < count; i++)
{
intersection[k] = intersection[k + 1];
}
count--;
}
}
}
//printing set
for (int i = 0; i < SIZE ; i++)
{
//printf("%d\n", intersection[i]);
if (intersection[i] != '\0')
{
printf("%d\n", intersection[i]);
}
}
return 0;
}
In the code above i was trying one method although it didn't work and instead made the program stuck after inputting all the elements. I am open to other methods as long it doesn't require an external library to run. Thanks
As i see it now , in the third loop where you checking your duplicates i thing that you have to increese k not i :
for (int k = j; j < count; k++), also you must decrise the size of j in your code under the count--;.So your code for checking duplicates seems right but , you want the intersection of this two arrays you made , so you dont have to check for duplicates because in the array intersection[SIZE] you will put only one number from the two arrays, so you will not have duplicates .You should check for duplicates if you wanted to make the union of this two arrays .I make some changings to your code acording what you want to create and this code here find the intersection from two arrays.Try this and delete the duplicate check because that makes your code to run to infinity . One last thing your intersection check must be replace whith this :
//Intersection check
int i = 0, j = 0,k=0; // k is for the intersection array !
while (i < SIZE && j < SIZE) {
if (array1[i] < array2[j])
i++;
else if (array2[j] < array1[i])
j++;
else if(array1[i]==array2[j]) // if array1[i] == array2[j]
{
intersection[k]=array2[j];
//printf("intersection[%d]=%d\n",i,intersection[i]);
intersectCount++;
k++;
i++;
j++;
}
}
printf("intersectCount=%d\n",intersectCount);

Attempt to arrange array elements in descending sequence (returning garbage values)

I wrote to program in C to attempt to print array elements in descending order. I wrote a nested loop which would find the maximum element of the array and the value of the element would be set to later 0. This process would be repeated for all the elements. However, in the output, I am getting the first 2-3 values as desired but the remaining values are garbage. Any suggestions?
int main() {
int i, j, n, k;
scanf("%d\n", &n);
int a[100], b[100];
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for (i = 0; i < n; i++) {
int max = a[i];
for (j = i; j < n; j++) {
if (a[j] > max) {
max = a[j];
b[i] = max;
}
}
for (k = 0; k < n; k++) {
printf("%d", a[k]);
if (a[k] == b[i]) {
a[k] = 0;
}
}
printf("\n");
}
for (i = 0; i < n; i++) {
printf("%d ", b[i]);
}
}
The main issue is that you only set b[i] = max; when you find a new max, but since you initialized max to be a[i] it could happen that it already holds the maximum value. So the if never executes, therefore b[i] is not written and there's garbage value in it. You should move this line from the if after that for loop.
Another issue is that you initialize j with i in this loop. You should initialize it to 0.
The changed part:
for (j = 0; j < n; j++) {
if (a[j] > max) {
max = a[j];
}
}
b[i] = max;

C - Getting a segmentation fault(core dumped) error in this simple program

This is a simple program, that finds teh smallest and largest element of a 10-array. I'm not sure why I'm getting the segmentation fault(core dumped) error.
#include <stdio.h>
int main(void) {
int i, j, min, array[10], max, n;
//This loop get user input for the elements of the array
for(i = 0; i < 10; i++) {
printf("Enter element number %d:", i);
scanf("%d", &n);
array[i] = n;
}
min = array[0];
max = array[0];
//This loop finds the smallest element of the array
for(j = 0; j < 10; j++) {
if(min > array[j]) {
min = array[j];
}
}
//This loop finds the largest element of the array
for(j = 9; j >= 0; j++) {
if(max < array[j]) {
max = array[j];
}
}
printf("smallest value is: %d", min);
printf("largest value is: %d", max);
return 0;
}
for(j = 9; j >= 0; j++)
should be
for(j = 9; j >= 0; j--)
if you want to iterate from the last to the first. You access array[10] in the second iteration, which is out of bounds.
Also there is no reason to iterate from the last to the first, so
for(j = 0; j < 10; j++)
would also work.
You can do the whole job in a single for loop (reading from stdin, look if it is larger than the max/smaller than the min) and so you do not need the array.
for (j = 9; j >= 0; j++)
Here you start from 9 and do j++!
do this:
for (j = 9; j >= 0; j--)
By the way you can do this
scanf("%d", array + i);
The loop below tries to point to a location that is beyond the assigned memory space.
for(j = 9; j >= 0; j++)
Instead try writing:
for(j=9; j >= 0; j--)
You may go for, an incrementing loop, as suggested by #mch, if you you'd like.
Also, as a suggestion, skip using the variable j here. You can use i instead. Won't be any issues, since you are assigning 0 to it in loop. You'd be saving 4 precious bytes.

% symbols keep printing when trying to print out a char 2D array in C

I'm new to C and I'm just trying to print out a two 2 array.
This bug has been annoying me all day and I'm not really sure whats going on.
#include<stdio.h>
void run(int);
main()
{
run(5);
return 0;
}
//Have to make it a character array as it needs to
//store numbers AND commas.
run(int x)
{
int size = 2*x -1;
char array[size][size];
int i = 0;
int j = 0;
for( i; i < size; i++){
for(j; j< size; j++){
array[i][j] = '1';
}
}
int k = 0;
int l = 0;
for( k; k < size; k++){
for(l; l< size; l++){
printf( "%c" , array[l][k]);
}
printf("%\n", "");
}
}
This is the output I get:
1%
%
%
%
%
%
%
%
%
You code has several mistakes:
The biggest problem is that your not initializing your loop counters where you should:
for(i; i < size; i++){
for(j; j < size; j++){
With that, i & j are left as they were prior to the for statement. The first section of these statements does nothing at all. While that's harmless for i (since it's initialized to 0 before the for), that's devastating for j, which never goes back to 0. Your code should be:
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
The same issue exists with k & l, and the same fix should be applied:
for(k = 0; k < size; k++){
for(l = 0; l < size; l++){
Next, you're "rotating" access in your array. When you fill the array with values, you have i in your outer loop and j in the inner loop, and you use them as [i][j]:
array[i][j] = '1';
Think of that as Out & In --> [Out][In].
When you print the array, you "rotate" that, k is outer & l is inner, and you use them as [l][k]:
printf("%c", array[l][k]);
That's like doing [In][Out].
While that's not a problem with all values being identical ('1'), and the matrix being square (width == height), it won't work with other values or dimensions, and is confusing.
Last, you're attempt to print a new line is wrong. You have a % specifier, but your not really using any valid character after that, and you don't need that anyway, just print:
printf("\n");
So, all together, here's what the code should be:
run(int x)
{
int size = 2*x -1;
char array[size][size];
int i,j;
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
array[i][j] = '1';
}
}
int k, l;
for(k = 0; k < size; k++){
for(l = 0; l < size; l++){
printf("%c", array[k][l]);
}
printf("\n");
}
}
(And as a side note, k & l are not really required, you can simply reuse i & j)

array counting sort segmentation fault

Hello i am trying to use counting sort to sort numbers that i read from a file. this is my code:
void CountingSort(int array[], int k, int n)
{
int i, j;
int B[100], C[1000];
for (i = 0; i <= k; i++)
{
C[i] = 0;
}
for (j = 1; j <= n; j++)
{
C[array[j]] = C[array[j]] + 1;
}
for (i = 1; i <= k; i++)
{
C[i] = C[i] + C[i-1];
}
for (j = 1; j <= n; j++)
{
B[C[array[j]]] = array[j];
C[array[j]] = C[array[j]] - 1;
}
printf("The Sorted array is : ");
for (i = 1; i <= n; i++)
{
printf("%d ", B[i]);
}
}
void max(int array[],int *k,int n){
int i;
printf("n je %d\n",n);
for (i = 0; i < n; i++)
{
if (array[i] > *k) {
*k = array[i];
}
}
}
int main(int brArg,char *arg[])
{
FILE *ulaz;
ulaz = fopen(arg[1], "r");
int array[100];
int i=0,j,k=0,n,x,z;
while(fscanf(ulaz, "%d", &array[i])!=EOF)i++;
fclose(ulaz);
n=i;
max(array,&k,n);
printf("Max je %d\n",k);
CountingSort(array,k,n);
return 0;
}
i have no errors but when i start my program i get Segmentation fault error. pls help! (dont read this bot is asking me to write some more details but i have none so i just write some random words so i can post my question and hopefully get an answer)
The problem is that your implementation of the counting sort is incorrect: it uses arrays as if they were one-based, while in C they are zero-based.
After carefully going through your loops and fixing all situations where you use a for loop that goes 1..k, inclusive, instead of the correct 0..k-1, the code starts to work fine:
int i, j;
int B[100], C[1000];
for (i = 0; i <= k; i++){
C[i] = 0;
}
for (j = 0; j < n; j++){
C[array[j]]++;
}
for (i = 1; i <= k; i++){
C[i] += C[i-1];
}
for (j = 0; j < n; j++) {
B[--C[array[j]]] = array[j];
}
printf("The Sorted array is : ");
for (i = 0; i < n; i++) {
printf("%d ", B[i]);
}
Demo.
Note: I modified some of the operations to use C-style compound assignments and increments/decrements, e.g. C[array[j]]++ in place of C[array[j]] = C[array[j]] + 1 etc.
The problem most likely is here
int B[100], C[1000]; // C has space for numbers up to 999
...
for (i = 1; i <= k; i++)
C[i] = C[i] + C[i-1]; // adding up till C[k] == sum(array)
for (j = 0; j < n; j++)
B[C[array[j]]] = array[j]; // B has space up to 99, but C[k] is sum(array)
so you're reserving space for C for a highest value of 999 but in B you're assuming that the sum of all input values is less than 100...
the resolution of your problem is to first probe the input array and get the maximum and the sum of all input values (and minimum if the range may be negative) and allocate space accordingly
edit: you probably meant j < n and not j <= n
Adding to dasblinkenlight's spot-on answer:
Is your input data guaranteed to be in the range [0, 999]? If it isn't, it's obvious that segmentation faults can and will occur. Assume that the maximum value of array is 1000. C is declared as
int C[1000];
which means that C's valid indices are 0, 1, 2, ... 999. But, at some point, you will have the following:
C[array[j]] = ... /* whatever */
where array[j] > 999 so you will be attempting an out-of-bounds memory access. The solution is simple: probe array for its maximum value and use dynamic memory allocation via malloc:
/* assuming k is the maximum value */
int * C = malloc((k + 1) * sizeof(int));
Note: an alternative to this, which would also nullify the need for an initialization loop to make all elements of C equal to 0, would be to use calloc, which dynamically allocates memory set to 0.
// allocate C with elements set to 0
int * C = calloc(k + 1, sizeof(int);
Another important factor is the range of your running indices: you seem to have forgotten that arrays in C are indexed starting from 0. To traverse an array of length K, you would do:
for (i = 0; i < K; ++i)
{
processArray(array[i]);
}
instead of
for (i = 1; i <= K; ++i)
{
processArray(array[i]);
}

Resources