How to input a two dimmensional array from a function - c

I currently am trying to find the grid size of a sample of data from using command window redirection. Every time I execute the program, my cmd stops working.
How do I fix this?
#include <stdio.h>
#include <math.h>
int inputData(int [][500]); //inputs the data and returns the rows by
columns.
int main(void){
int n = 0;
int data[n][n];
printf("Grid size: %dx%d", inputData(data),inputData(data));
return 0;
}
int inputData(int data[][500]){
int i;
int j;
for(i = 1; i <= 500; i++){
for(j = 0; j <= 500; j++){
scanf("%d", &data[i][j]);
}
}
return j;
}

First, n has be set to 500 in main.
Second, in the function, the iteration of i and j should be from 0 to 499.
Remember that in C, the index starts from 0, not 1.

n = 0, but you iterate through a 500x500 array, so you get a segmentation fault. Make n = 500

Related

Why does my program compile but not do anything?

#include <stdio.h>
#include <cs50.h>
#include <math.h>
int * get_digs(long card, int digs, int idigs[]);
int main()
{
long card = get_long("Number: ");
int digs = ceil(log10(card));
int idigs[digs];
get_digs(card, digs, &idigs[digs]);
for(int k = 0; k == digs; k++) // This loop is to check if the program is doing what I'm
{ // asking it to do.
printf("%i", idigs[k]);
}
}
int * get_digs(long cd, int dg, int idg[])
{
int j = dg;
int dig = 0;
for(int i = 0; i == dg; i++)
{
dig = floor(cd / pow(10, j));
j--;
idg[i] = dig % 10;
}
return 0;
}
This program is supposed to take an input from the user, let's say a credit card, get its digits and store them on an array. The program compiles, but it doesn't even print the for loop on the main function... It just asks for input. What am I doing wrong?
The second expression in a for loop's control block is a condition for iterating, not for breaking from the loop. Thus, this for loop ...
for(int k = 0; k == digs; k++)
... executes the loop body only if k is equal to digs, and that will be true the first time the condition is checked only if digs is zero, which you (reasonably) do not expect to be the case. Furthermore, unless k were also modified inside the loop body, which it isn't in your code, the body would never execute more than once. It's similar in effect, then, to if (k == digs), and of course the loop body is not executed even once.
The standard idiom for what you are trying to do uses a < expression in the condition:
for (int k = 0; k < digs; k++)

My pointer in an array doesn't work as it supposed to

I wanted to create a function, that would accept an 1:array_of_int, and 2:size_of_array, then return sum of the 3 biggest int. Code follows:
#include <stdio.h>
#include <stdlib.h>
int max_3(int arr[], int asize)
{
int max_arr[3];
int max =0;
int sum = 0;
int* pi;
for(int j=0; j<3; j++)
{
for(int i =0; i<asize;i++)
{
if(arr[i] > max)
{
max = arr[i];
pi = (arr + i); // to know the address of the max int of 'i' cycle
}
}
max_arr[j] = max;
*pi = 0; // make the max int = 0 so that the next 'i' cycle doesnt have the previous max in it
//(so it can look for another max value - the second one)
}
for(int i=0; i<3; i++)
sum += max_arr[i];
return sum;
}
int main (int argc, char** argv) {
int arr[6] = {1,5,9,12,16,14};
printf("%i\n",max_3(arr, 6));
return (EXIT_SUCCESS);
}
The pointer pi doesn't make the value of the current max value 0, and the next cycle in for (int i..) make the biggest one again as from the previous. So instead of returning max val1 + val2 + val3, it returned 3 * val1 (the biggest one) -- in my particular example - it printed out 48 instead of 42 (12 + 16 + 14) - as it should. But how when I make the value of address (which my pointer point to) as 0? I do not understand that properly.
Your if statement:
if (arr[i] > max)
isn't going to be entered after the first time you find max (i.e. when j > 0).
You need to zero it after:
max_arr[j] = max;
max = 0;
The following proposed code:
performs the desired functionality
is very straight forward in its' algorithm
incorporates a bubble sort for selecting the top three entries in the array
eliminates the 'magic' number 6
modifies the second parameter to type size_t as that is the type returned by sizeof()
the expression: sizeof(arr)/sizeof(arr[0]) lets compiler calculate number of entries in array
the statement: int arr[] = {1,5,9,12,16,14}; lets compiler allocate room for array
avoids modifying the original array, when sorting
and now, the proposed code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // memcpy()
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// A function to implement bubble sort
void bubbleSort(int arr[], size_t n)
{
size_t i;
size_t j;
for (i = 0; i < n-1; i++)
{
// Last i elements are already in place
for (j = 0; j < n-i-1; j++)
{
if (arr[j] > arr[j+1])
{
swap(&arr[j], &arr[j+1]);
}
}
}
}
int max_3(int arr[], size_t asize)
{
int localArray[ asize ];
memcpy( localArray, arr, asize*sizeof( int ) );
// sort array
bubbleSort( localArray, asize );
// calculate sum of max 3 entries
int sum = localArray[asize-1] + localArray[asize-2] + localArray[asize-3];
return sum;
}
int main ( void )
{
int arr[] = {1,5,9,12,16,14};
printf( "%i\n", max_3( arr, sizeof(arr)/sizeof(arr[0])) );
return (EXIT_SUCCESS);
}
a run of the proposed code results in:
42
After the very first iteration of the outer loop (the loop for(int j=0; j<3; j++)) the value of max and pi will never change.
In that first iteration of the outer loop, you will find that the fifth element in the array will be largest, max will be equal to 16 and pi will point to that element. You set max_arr[0] to 16 and set *pi to zero. Then the outer loop starts over with max still being equal to 16. And now there will be no value in the array that will be equal or larger than that. So you set max_arr[1] to 16 as well, and set *pi (where pi is still pointing to the fifth element) to zero again. And the same thing the next iteration.
The natural solution would be to define max and pi inside the outer loop:
for(int j=0; j<3; j++)
{
// The variables will be redefined and reinitialized each iteration of the loop
int max = 0;
int *pi;
for(int i =0; i<asize;i++)
{
if(arr[i] > max)
{
max = arr[i];
pi = (arr + i); // to know the address of the max int of 'i' cycle
}
}
max_arr[j] = max;
*pi = 0; // make the max int = 0 so that the next 'i' cycle doesnt have the previous max in it
//(so it can look for another max value - the second one)
}
There are a few other problems with the code, like for example the possibility that pi will never be initialized. I leave it as an exercise to the reader to figure when that will happen and how to solve it.

Generating and storing random numbers in array in c

I have to make an array containing 25 random numbers using a function to define the random numbers but keep getting it to either display only one number at a time (instead of all of them cell by cell) or simply displaying incorrectly i.e. 0. Here is what I have so far.
edit Code changed to correct stupid mistakes I missed rushing, however still unsure how to call funct as I am getting "too few arguments for funct 'get_value', apologies if this seems trivial but I am extremely new to coding thank you for your time.
int get_value (int t);
int main()
{
srand(time(NULL));
int temp[25], n;
for(n=0; n<25; n++)
{temp[n] = rand() %(40)+60;
printf("value of %d at cell %d \n", n, temp[n]);}
return 0;
}
//function get_value()
//needs to return rand # <-> 60 and 100 seed rand
//use rand %40+60 to ensure value is <-> 60 and 100
int get_value (int t)
{
return rand() %(40)+60;
}
You have some syntax errors
for loop should be like this
for(n=0; n<25; n++)
{
temp[n] = get_value(n); //in your prog u have written temp[t], t isnt defined
printf("value at cell %d is %d \n", n, temp[n]);
} // you also missed the braces
You are assigning value to temp[t], but you haven't declared t. In any case, it should be temp[n].
The scope of the variable t is only in your get_value function.
For more information about scopes
//I think here's what you want to do.
#include <stdio.h>
#include <time.h>
int main()
{
srand(time(NULL));
int temp, i, j, h;
int num_array[40];
int i_need_25[25];
//here's how im getting random numbers without repeating a number.
//first, fill the array with numbers between
for(i = 0; i < 41; i++)
{
num_array[i] = i + 60;
}
//then here's how we shuffle it
for(i = 0; i < 41; i++)
{
j = rand() % 41;
temp = num_array[j];
num_array[j] = num_array[i];
num_array[i] = temp;
}
//final process is to print the first 25 elements as you have said you need 25.
for(i = 0; i < 25; i++)
{
printf("%d ", num_array[i]);
}
printf("\n\n");
//or you can also store the first 25 elements on separate array variable.
for(i = 0; i < 25; i++)
{
i_need_25[i] = num_array[i];
printf("%d ", i_need_25[i]);
}
return 0;
}

Segfault at initialization of simple for loop

I have to be losing my mind here. I'm getting a segfault at the line for(i = 0; i < N; i++) {. I've never encountered anything like this. Here's the full code:
#include <stdio.h>
#include <time.h>
#define N 2400
#define M 2000
#define P 500
int main() {
int a[N][N];
int b[N][N];
int c[N][N];
int i, j;
// Initialize matrix A
for(i = 0; i < N; i++) {
for(j = 0; j < M; j++) {
a[i][j] = j-1+2;
}
}
// Initialize matrix B
for(i = 0; i < M; i++) {
for(j = 0; j < P; j++) {
b[i][j] = i-j+1;
}
}
}
First : you have declared a, b and c as [N][N] matrix, but you initialize them as if they were [N][M] and [M][P] matrix. Considering N > M > P, that should not cause a segfault, but the intent is not clear.
Second, if you replace your defines by :
#define N 10
#define M 5
#define P 2
Your program work. This is because local variables a and b are stored on the stack and your stack is limited in size. Consult your compiler and your system documentation to know exactly the limits imposed.
To avoid such problem, allocate your memory using malloc or equivalent function, that allocate memory on the heap, which is less constrained.

Make a program run linear in C

So based in the following problem from cumulative sum query I created the solution. But is any other way to solve the problem in C with linear complexity O(N)?
Problem description:
William Macfarlane wants to look at an array.
You are given a list of N numbers and Q queries. Each query is
specified by two numbers i and j; the answer to each query is the sum
of every number between the range [i, j] (inclusive).
Note: the query ranges are specified using 0-based indexing.
Input
The first line contains N, the number of integers in our list (N <=
100,000). The next line holds N numbers that are guaranteed to fit
inside an integer. Following the list is a number Q (Q <= 10,000). The
next Q lines each contain two numbers i and j which specify a query
you must answer (0 <= i, j <= N-1). Output
Output
For each query, output the answer to that query on its own line in the
order the queries were made.
Here is the solution:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
struct node {
int first;
int last;
};
int sum_array(int *array, int first, int last) {
int sum = 0;
for (int i = first; i <= last; i++) {
sum += array[i];
}
return sum;
}
int main() {
FILE* input = fopen("share.in","r");
int N = 0;
fscanf(input,"%d",&N);
int *array = (int*)malloc(N * sizeof(int));
for (int i = 0; i < N; i++) {
fscanf(input,"%d",&array[i]);
}
int Q = 0;
fscanf(input,"%d",&Q);
struct node query[Q];
for (int i=0; i < Q; i++) {
fscanf(input,"%d",&query[i].first);
fscanf(input,"%d",&query[i].last);
}
fclose(input);
int sum = 0;
for ( int i = 0; i < Q ; i++) {
int first = query[i].first;
int last = query[i].last;
sum = sum_array(array,first,last);
printf("Number of queries : %d , sum is %d\n",i ,sum);
}
free(array);
return 0;
}
Update:
The answer given is good. But for some reason I couldn't make it work.
So here is the code rewritten and if someone can explain me what I do wrong I will be happy! Keep in mind we want the range to be [first,last]
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
struct node {
int first;
int last;
};
int sum_array(int *array, int first, int last) {
int sum = 0;
for (int i = first; i <= last; i++) {
sum += array[i];
}
return sum;
}
int main() {
FILE* input = fopen("share.in","r");
int N = 0;
fscanf(input,"%d",&N);
int *array = (int*)malloc(N * sizeof(int));
int *integralArray = (int*)malloc(N * sizeof(int));
for (int i = 0; i < N; i++) {
fscanf(input,"%d",&array[i]);
integralArray[i] = array[i] + ((i > 0) ? array[i-1] : 0);
}
int Q = 0;
fscanf(input,"%d",&Q);
struct node query[Q];
for (int i=0; i < Q; i++) {
fscanf(input,"%d",&query[i].first);
fscanf(input,"%d",&query[i].last);
}
fclose(input);
int sum = 0;
for (int i = 0; i < Q ; i++) {
int first = query[i].first;
int last = query[i].last;
sum = integralArray[last] - integralArray[first - 1];
printf("Number of queries : %d , sum is %d\n",i ,sum);
}
free(array);
return 0;
}
You'd form the integral array. Modify to something like:
int *array = (int*)malloc(N * sizeof(int));
int *integralArray = (int*)malloc(N * sizeof(int));
for (int i = 0; i < N; i++) {
fscanf(input,"%d",&array[i]);
integralArray[i] = array[i] + ((i > 0) ? integralArray[i-1] : 0);
}
So the element at integralArray[i] is the sum of all elements in array from 0 to i.
Then, to get the sum from a to b, where a > b, integralArray[b] is the sum from 0 to b and integralArray[a] is the sum from 0 to a so you can just compute integralArray[b] - integralArray[a] to get the total from a to b. Intuitively, integralArray[b] includes the numbers you want but it also includes the numbers up to and including a. You don't want those so you take them off again.
Vary appropriately for inclusion or exclusion of the number at a and the number at b. That as given will include the number at b but not that at a. You could adjust your integralArray to be one earlier (so integralArray[b] is the sum from 0 to b-1) or adjust your indices.

Resources