Why does my program compile but not do anything? - c

#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++)

Related

Is there a way to make a function for calculating 10 to the x exponent in C? "ten_to_the(x exponent)"

I need to multiply a number by 10 to the (x) power, depending on the exponent I may require.
I know there is a function, in the <math.h> library, but I was wondering if I could make my own function to achieve basically the same but only for 10, not any number. It´s for course homework, but since we haven´t been told about this library, I want to try to achieve it without said power() function.
Here's my code; it does compile, but I get some weird number instead of the intended 5000.
#include <cs50.h>
#include <stdio.h>
int ten_to_the(int n);
int main(void) {
int x = 50;
x *= ten_to_the(2);
printf("%.i\n", x);
}
int ten_to_the(int n) {
n = 1;
for (int i = 0; i < n; i++) {
n *= 10;
}
return n;
}
Because you multiple n by 10 on each iteration of the loop, i < n can never become true. In practice, n keeps getting bigger until it overflows and becomes negative.
Use another variable to keep track of the result separate from the number of iterations you need to calculate.
Instead of this:
int ten_to_the(int n)
{
n = 1;
for (int i = 0; i < n; i++)
{
n *= 10;
}
return n;
}
This:
int ten_to_the(int n)
{
int result = 1;
for (int i = 0; i < n; i++)
{
result *= 10;
}
return result;
}

Going through user input and multi-dimensional arrays in C

I am trying to make a code where a user has 5 tries to guess a number and if any of the 3 series of numbers within Winning_order then both of the for loops will break. The usersInputs stores the users inputs to be compared with Winning_order. So for example, if the number 1,2,3 or 1,2,4,5,3 is inputted by the user the loop will print There is a Correlation and the for loops will stop. If the input is 7,8,9,3,2 since no 3 numbers are present within the Winning_order the loops will just stop. There is a problem with the match_arrays function and I do not know how to go about stopping the nested for loops if the if statement is valid.
Checking if the function has a correlation
int match_arrays(int *arr1, int *arr2, int len) {
for (int p = 0; p < len; p++) {
if (arr1[p] != arr2[p]) {
return 0;
}
}
return 1;
}
main() function
int main(void)
{
int Winning_order[3][3] = {{1,2,3}, {1,4,7}, {2,5,8}};
int input = 0;
int usersInputs[5] = {0};
for (int i = 0; i <= 4; i++){
printf("\nPlayer input: ");
scanf("%d", &input);
usersInputs[i] = input;
for (int p = 0; p < 5; p++) {
if (match_arrays(usersInputs, Winning_order[p], 3)) {printf("There's a Corelation");}
}}
return 0;
}
There are different ways of approaching breaking a double loop (or to generalize: a nested loop), this solution is not the optimal, the best, or the recommended, but it works. I fixed the indentation and some naming issues, but I won't fix anything else.
This is a working snippet:
#include <stdio.h>
int match_arrays(int *arr1, int *arr2, int len) {
for (int p = 0; p < len; p++) {
if (arr1[p] != arr2[p]) {
return 0;
}
}
return 1;
}
int main(void) {
int winning_order[3][3] = {{1,2,3}, {1,4,7}, {2,5,8}};
int input = 0;
int users_inputs[5] = {0};
for (int i, break_i = 0; !break_i && i < 5; i++){
printf("\nPlayer input: ");
scanf("%d", &input);
users_inputs[i] = input;
for (int p = 0; p < 3; p++) {
if (match_arrays(users_inputs, winning_order[p], 3)) {
printf("There's a Corelation\n");
break_i = 1;
break;
}
}
}
return 0;
}
I made this easy for you to understand. I added a new flag to the outer for loop called break_i with an initial falsy value. Simultaneously, I added a short circuit && operation to the for loop.
Inside your inner loop, I added a break_i = 1 statement that will make the outer loop stop. Immediately after that, I use the break statement to break the inner loop.
P.S.: I also fixed the index out of bounds pointed out by #kaylum. You may want to use a macro or sizeof() next time, but that's beyond the scope of your question.

I can't use an existent variable inside a for loop

This code should make a sum of the numbers in the main diagonal of a matrix.
#include <stdio.h>
#define RIG 2
#define COL 5
void sum(unsigned int a[RIG][COL]);
int main(){
unsigned int a[RIG][COL] = {{1,2,3,4,5},{6,7,8,9,10}};
sum(a);
}
void sum(unsigned int a[RIG][COL]){
unsigned int c = 0;
unsigned int j = 0;
if (RIG<=COL){
int n = RIG;
}
else{
int n = COL;
}
for (size_t i=0;i<=n-1;++i){
c += a[i][j];
j += 1;
}
printf("%d\n", c);
}
Output:
matrix_sum.c:28:21: error: use of undeclared identifier 'n'
for (size_t i=0;i<=n-1;++i){
^
1 error generated.
I don't get why I can't use the n variable inside the for loop. How can I do that?
This
if (RIG<=COL){
int n = RIG;
}
else{
int n = COL;
}
does not scope n the way you might think it does. Scoping rules are better explained here, but in short: n exists only within each branch of the if/else block. As such, when you attempt to access n in your for-loop later on, it no longer exists!
This is trivially remedied by bringing n into scope, e.g.
int n = COL;
if (RIG <= COL) {
n = RIG;
}
for (size_t i = 0; i <= n - 1; ++i) {
c += a[i][j];
j += 1;
}

How to return a double pointer from a function and send it as input into another function?

I am new to programming and am trying to use two functions for matrix (2D array) operations, where the output of one function is the input for the next.
However, I do not find a way to correctly deliver the values from one function to another. When I print the outputs of the first function in main (), they are correct, but when I input them into the 2nd function and print them, the values make no sense. I have tried it a lot of ways, but it probably fails due to my lack of understanding double pointers.
I am thankful for any hint or advise!
#include <stdio.h>
#include <stdlib.h>
int** td (int r_in, int c_in, int r_p, int c_p, int input[][c_in],int params[][c_p]){
int i, j, k;
int**y_td;
// memory allocation
y_td = (int*)malloc(sizeof(int*)*r_in);
for (i=0; i < r_in; i++){
y_td[i] = (int*)malloc(sizeof(int)*c_p);
}
//
for (i=0; i < r_in; i++){
for (j=0; j < c_p; j++){
y_td[i][j]=0; // Initialization
for (k=0; k < c_in; k++){
y_td[i][j]+= input[i][k]*params[k][j];
}
}
}
return y_td;
}
int** cnv (int r_in, int c_in, int filter, int f_size, int input[][c_in], int params[][f_size][c_in]){
int x,i,j,k,l,m,n;
int min_len = ((r_in < f_size)? r_in:f_size);
int max_len = ((r_in > f_size)? r_in:f_size);
int r_out = max_len - min_len + 1;//rows_out
int kernel;
int** y_cnv;
// Print input to check if it was correctly transmitted to the function
printf("Input CV (should be equal to TD result):\n");
for (i=0;i<r_in;i++){
for (j=0;j<c_in;j++){
printf("%d ", input[i][j]);
}
printf("\n");
}
printf("\n\n");
//memory allocation
y_cnv = (int*)malloc(sizeof(int*)*r_out);
for (i=0; i < r_out; i++){
y_cnv[i] = (int*)malloc(sizeof(int)*filter);
}
//
for (i=0; i < filter; i++){
for (k=0; k < r_out; k++){
y_cnv [k][i]=0; //initialize
}
for (j = 0; j < c_in; j++){
for (n = min_len-1; n < max_len; n++){
x = n-min_len+1;
for (m= 0; m < r_in; m++){
kernel = (((n-m) < min_len && (n-m) >= 0)? params[i][n-m][j]:0);
y_cnv[x][i] += input[m][j]*kernel;
}
}
}
}
return y_cnv;
}
int main() {
// create test arrays
int A [4][2]= {{1,1},{2,2},{3,3},{4,4}};
int B [2][3]= {{1,2,3},{2,3,4}};
int C [2][2][3]= {{{1,1,1},{2,2,2}},{{3,3,3},{4,4,4}}};
int** matrix;
int i, j;
matrix = td(4,2,2,3,A,B);
// print the result of first function, which is input in 2nd function
printf("The TD result is:\n");
for (i=0;i<4;i++){
for (j=0;j<3;j++){
printf("%d ",matrix[i][j]);
}
printf("\n");
}
printf("\n\n");
matrix = cnv(4,3,2,2,matrix,C);
return 0;
}
I expect the matrix printed in main () after the first function td () to be the same as when I read it in the second function cnv () and print it there, but it is not.
take a look at this question. You were hit by the same underlying problem.
Turning
int** cnv (int r_in, int c_in, int filter, int f_size, int input[][c_in], int params[][f_size][c_in])
into
int** cnv (int r_in, int c_in, int filter, int f_size, int** input, int params[][f_size][c_in])
fixes the problem you asked for.
The reason is that you allocate an array of pointers called y_td in your first function. Each of this pointers is a number naming a memory segment where you stored some real numbers. By using int input[][c_in] you tell the computer to interpret these pointers as integer numbers and when you print them you get the addresses in memory instead of the expected values, because then input[x][y] is translated to *((int *)input+x*c_in+y).
Please allow me one more comment: You should follow the comments below the question and care for all compiler warnings: If there is a warning you should treat it as an compiler error unless you exactly know what you are doing, especially in C. Your code contains some possible problem sources like the one above.

How to input a two dimmensional array from a function

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

Resources