Printing out a matrix of doubles - c

My professor gave us some code in class that will read in a matrix. However, it wont print out double values. If I have the following in a file
6.4 5.6 6.7
4.3 5.7 2.1
9.8 7.8 9.2
the code will round them down rather than printing out the actual double value. What needs to be changed? I have tried changing it to a double matrix, and printing it out using %g, etc.
#include <stdio.h>
#include <stdlib.h>
float** readMatrix(int *nRows, int *nCols);
main() {
//Holds our matrix of numbers
int nums[30][30];
float** m;
int r = 0, c = 0, i, j;
m = (float**)readMatrix(&r, &c);
for (i = 0; i < r; i++){
for (j = 0; j < c; j++) printf("%1.0f ", m[i][j]);
printf("\n");
}
}
//Read a matrix from standard input
float** readMatrix(int *nRows, int *nCols) {
int i = 0;
int j = 0;
int k = 0;
char c;
*nRows = 0; //The number of rows
*nCols = 0; //The number of columns
int nums[30][30];
char num[10];
while (1) {
//Read in the numbers on a row
j = 0; // j = the index of the number on the row - start at zero
while (1) {
//We will re-use the index i, so set to zero
i = 0;
//Read characters from standard input until a space or EOL
while ((c = getchar()) != ' ' && c != 10 && c != EOF) {
num[i++] = c;
}
//Null terminate the array of characters
num[i] = 0;
//Changes the array of characters to a float
nums[k][j++] = atof(num);
//If we are at the end of the line or end of file - break
if (c == 10 || c == EOF) break;
//Set the number of numbers
(*nCols) = j + 1;
}
//Stop if you are at the end of file
if (c == EOF) break;
//Go to the next row
k++;
} //End while(1) outer loop
*nRows = k;
//Allocate memory for the row pointers
float** retMat = (float**)malloc((*nRows)*sizeof(float*));
//Allocate memory for the rows themselves
for (i = 0; i < (*nRows); i++) retMat[i] = (float*)malloc((*nCols)*sizeof(float));
//Copy the nums matrix into the return matrix
for (i = 0; i < (*nRows); i++) for (j = 0; j < (*nCols); j++) retMat[i][j] = nums[i][j];
return retMat;
}

You are first reading into nums array which is of type int. Change that to float.
nums[k][j++]=atof(num);
atof returns float which is rounded down to int.
------EDIT-----------
printf("%1.0f ", m[i][j]);
This is reason why it prints wrong now. Check it.

Related

How to make competitive coding solutions more efficient (BIT wise operations)?

How do I make my code more efficient (in time) pertaining to a competitive coding question (source: codechef starters 73 div 4):
(Problem) Chef has an array A of length N. Chef wants to append a non-negative integer X to the array A such that the bitwise OR of the entire array becomes = Y .
Determine the minimum possible value of X. If no possible value of X exists, output -1.
Input Format
The first line contains a single integer T — the number of test cases. Then the test cases follow.
The first line of each test case contains two integers N and Y — the size of the array A and final bitwise OR of the array A.
The second line of each test case contains N space-separated integers A_1, A_2, ..., A_N denoting the array A.
Please don't judge me for my choice of language .
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int* binary_number(int n) // returns pointer to a array of length 20(based on given constrains) representing binary
{
int* ptc;
ptc = (int*) malloc(20*sizeof(int));
for(int i = 0; i < 20; i++)
{
if((n / (int) pow(2,19-i)) > 0){*(ptc + i) = 1;}
else {*(ptc + i) = 0;}
n = n % (int) pow(2,19-i) ;
}
return ptc;
}
int or_value(int* ptc, int n) // Takes in pointers containing 1 or zero and gives the logical OR
{
for(int k = 0; k < n; n++)
{
if(*ptc == *(ptc + 20*k)){continue;} // pointers are 20 units apart
else{return 1;break;}
}
return *ptc;
}
int main(void) {
int t; scanf("%d", &t);
for (int i = 0; i < t; i++)
{
int n, y;
scanf("%d %d", &n, &y);
int a[n];
for(int j = 0; j < n ; j++)
{
scanf("%d", &a[j]);
}
int b[20*n];
for (int j = 0; j < n; j++)
{
for (int k = 0; k < 20; k++)
{
b[20*j + k] = *(binary_number(a[n])+k);
}
}
int c = 0;
int p = 0;
for (int j = 0; j < 20; j++)
{
if ((*(binary_number(y) + j) == 1) && (or_value((&b[0] + j),n) == 0)){c = c + pow(2,19 - j);}
else if ((*(binary_number(y) + j) == 0) && (or_value((&b[0] + j),n) == 1)){p = 1; break;}
}
if (p==1){printf("-1");}
else {printf("%d\n", c);}
}
return 0;
}

Converting couple of integers into one integer in C

In doing an assignment, in which:
Program prints out the sum in the form of the following text
1 + 22 + 333 + 4444 + . . . + nn. . . n }n
and its result. The number n ∈ {1, 2, . . . , 9} is provided by the user
I'm stuck at the point where I don't know how to glue the numbers into one integer, so how to convert "333" into 333, etc.
Here's my code:
#include <stdio.h>
#include <string.h>
int main()
{
printf("Program calculates a sum.\nAutor: Jakub Drozd\n");
int n;
int sum = 0;
printf("Enter the length of the sum (no more than 9): ");
while (scanf_s("%d", &n)!=1 || n < 1 || getchar()!='\n')
{
printf("Wrong input, enter the length of the sum: ");
int c;
while ((c = getchar()) != '\n' && c != EOF)
;
}
for (int i = 1; i <= n; i++)
{
if (i == 1);
else { printf(" + "); }
for (int j = 1; j <= i; j++)
{
printf("%d", i);
}
}
printf("\nEnd of the program\n");
return 0;
}
As you can see, The program correctly displays the numbers to be added, but I don't know how to cast them into integers to sum them up.
Instead of printing out the individual digits, add them together to form the actual value, and then add them to a sum that you present.
The creation of the numbers could be like
int number = 0;
for (int j = 1; j <= i; ++j)
{
number = number * 10 + i;
}
Then adding the numbers is as simple as creating a variable to hole the sum, and adding to it:
int sum = 0;
// ...
sum += number;

C printing an array of two dimensions

In the following code, I am trying to read char by char from a file and store each char in a two dimensional array. After that I want to print each char in the array with its coordinates (i and j):
#include <stdio.h>
#pragma warning(disable:4996)
int main(){
char grid[3][5];
FILE *file;
file = fopen("input.txt", "r");
int c;
if (file == NULL){
perror("Error in reading the file");
}
else{
int j=0;
for (int i = 0; i < 3; i++)
{
while (j<5)
{
grid[i][j] = fgetc(file);
j++;
}
j = 0;
}
}
int length = sizeof grid / sizeof grid[0][0];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%c %d %d \n", grid[i][j], i, j);
}
}
printf("\n");
return 0;
}
The file that I read from looks like:
ABCDE
FGHIJ
KLMNO
I want the result to be like:
A 0 0
B 0 1
...
But the real results that I got is:
A 0 0
B 0 1
C 0 2
D 0 3
E 0 4
1 0
F 1 1
G 1 2
H 1 3
I 1 4
J 2 0
2 1
K 2 2
L 2 3
M 2 4
As you can see, the second row is printed with a space first and the same with the third row. Also, the last two letters N and O are not printed. Can someone help me solving this issue?
Change this bit of code
for (int i = 0; i < 3; i++)
{
while (j<5)
{
grid[i][j] = fgetc(file);
j++;
}
j = 0;
}
To add in an if statement which will check to make sure the character it read in is not a newline character \n. The finished code will look like this:
for (int i = 0; i < 3; i++)
{
while (j<5)
{
char c = fegetc(file);
if(c != '\n')
{
grid[i][j] = fgetc(file);
j++;
}
}
j = 0;
}
Fiddling Bits suggested that the inner loop be changed to a for loop (for readability). I would agree, however it does have the drawback of having to put j-- in the else part of the if statement, versus not even needing an else statement. You can view the above fix and this fix with the inner loop changed to a for loop, and decide which one you think has the best readability in this case. This code represents that change as well as the fix for the initial problem:
for (int i = 0; i < 3; i++)
{
for(int j = 0; j < 5; j++)
{
char c = fegetc(file);
if(c != '\n')
{
grid[i][j] = fgetc(file);
} else {
j--;
}
}
}
Try to add another fgetc(file); after the j=0;
(Without any assignment).
It will pull the new line char from your file

How to normalize a matrix in C?

How to normalize a matrix?
Suppose I have a 2x3 matrix:
1 2 3
4 5 6
The normalized matrix would be:
1/sqrt(pow(2,2) + pow(3,2)) 2/sqrt(pow(2,2) + pow(3,2)) 3/sqrt(pow(2,2) + pow(3,2))
4/sqrt(pow(5,2) + pow(6,2)) 5/sqrt(pow(5,2) + pow(6,2)) 6/sqrt(pow(5,2) + pow(6,2))
This is my sample code:
#include <stdio.h>
#include <conio.h>
#include <math.h>
int main(){
int rows, cols, rowCounter, colCounter, r, c;
int initial[100], inputMatrix[100][100], rowSum[100] = {0}, norm[100][100], square[100] = {0};
printf("Enter size of a matrix\n");
scanf("%d %d", &rows, &cols);
printf("Enter matrix of size %dX%d\n", rows, cols);
/* Input matrix */
for(rowCounter = 0; rowCounter < rows; rowCounter++){
for(colCounter = 0; colCounter < cols; colCounter++){
scanf("%d", &inputMatrix[rowCounter][colCounter]);
}
}
for(r = 0; r < rows; r++)
{
for(c = 1; c < cols; c++)
{
float a;
a == inputMatrix[r][c];
square[r] += pow(a, 2);
}
printf("%.2lf ", square[r]);
}
for(rowCounter = 0; rowCounter < rows; rowCounter++)
{
for(colCounter = 0; colCounter < cols; colCounter++)
{
norm[rowCounter][colCounter] == (inputMatrix[rowCounter][colCounter]) / sqrt(square[rowCounter]);
}
}
printf("\nNormalized Matrix:\n");
for(rowCounter = 0; rowCounter < rows; rowCounter++)
{
for(colCounter = 0; colCounter < cols; colCounter++)
{
printf("%.3lf ", norm[rowCounter][colCounter]);
}
printf("\n");
}
getch();
return 0;
}
Why are you using == here:
for(r = 0; r < rows; r++)
{
for(c = 1; c < cols; c++)
{
float a;
a == inputMatrix[r][c]; //look here
square[r] += pow(a, 2);
}
It should be:
for(r = 0; r < rows; r++)
{
for(c = 1; c < cols; c++)
{
float a;
a = inputMatrix[r][c];
square[r] += pow(a, 2);
}
The same here:
norm[rowCounter][colCounter] == (inputMatrix[rowCounter][colCounter]) / sqrt(square[rowCounter]);
It should be:
norm[rowCounter][colCounter] = (inputMatrix[rowCounter][colCounter]) / sqrt(square[rowCounter]);
And you should be careful here:
int initial[100], inputMatrix[100][100], rowSum[100] = {0}, norm[100][100], square[100] = {0};
Are you sure about use int for all of this declarations?
I think you should use double or float instead, at least in some of them.
There are some problems in your code, I'll try to address the most important ones.
Your norm matrix is a 2D array of int as inputMatrix, but you have to use an array of float or double to correctly store the result and to perform the right calculation. In C if both of the terms of a division are integers types an integer division (like: 3/2 = 1, not 1.5) is performed, which is not what you need.
Another mistake is to use == instead of = to perform an assignment. In C == is the 'equal to' relational operation.
EDIT
As #chux pointed out it would be wiser to choose a more accurate type for a and square[]. Using long long int will (may) prevent numeric overflow in case the elements of the matrix are too big for their square or the sum of them to be reprensented by an int.
Be aware that if you decide to use double instead there are other subtle numerical issues concernig the sum of small number (and the order in which it is performed) represented by floating point types. So, as a partial remedy, you can use long double (if it really has more precision then double in your environment) for a and square.
EDIT 2
In the question and in comment you say that the first element of each row of the matrix is supposed to be "constant in the matrix" so it doesn't take part to the sum of squares in your code and in the example you gave, but in both of them they are updated in the next loop. I'm not sure of what is going on, so I corrected my code to mimic the behavior of yours.
Here is a working corrected version of your code:
#include <stdio.h>
#include <math.h>
int main() {
int rows, cols, r, c;
// you may think about dynamical allocation here
int inputMatrix[100][100], rowSum[100] = {0};
// it's better to use a type that can manage bigger numbers to avoid numeric overflow
long long int a, square[100] = {0};
// your starting matrix can be a matrix of int but the normalized one need to
// contain floating point numbers
double norm[100][100], k;
printf("Enter size of a matrix\n");
scanf("%d %d", &rows, &cols);
printf("Enter matrix of size %dX%d\n", rows, cols);
/* Input matrix */
for ( r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) {
scanf("%d", &inputMatrix[r][c]);
// ^^ if you are scanning integer numbers...
}
}
printf("\nrows: %d cols: %d elements:\n",rows,cols);
for( r = 0; r < rows; r++) {
for( c = 0; c < cols; c++) {
printf("%d ", inputMatrix[r][c]);
// ... ^^ you should print integer numbers
}
printf("\n");
}
for (r = 0; r < rows; r++) {
for (c = 1; c < cols; c++) {
// ^^^ I don't know why you skip this here
a = inputMatrix[r][c];
//^ You have to assign, not to compare!
square[r] += a * a;
// ^^^^^ no need to call pow()
}
printf("Sum of squares of row %d: %lld\n",r,square[r]);
// square contains int ^^
// It would be nice and safer if you check here if square == 0 to avoid a
// division by zero and probably detect bad input data
}
for ( r = 0; r < rows; r++ ) {
// It's far more efficient to precalculate this term, even if compilers
// could be smart enough to do it for you. You may want to store those
// values in an array of doubles instead of the (sum of) squares
k = 1.0 / sqrt(square[r]);
for( c = 0; c < cols; c++ ) {
norm[r][c] = k * inputMatrix[r][c] ;
// again, ^ assign not compare
}
}
// you can add the printf to the previous loop...
printf("\nNormalized Matrix:\n");
for( r = 0; r < rows; r++) {
for( c = 0; c < cols; c++) {
printf("%.3lf ", norm[r][c]);
// ^^^^^ norm contains double
}
printf("\n");
}
return 0;
}
I keep the input matrix of integer type, but it would be better to use double for that too. As i added a print loop for the original matrix, the final output is:
rows: 2 cols: 3 elements:
1 2 3
4 5 6
Sum of squares of row 0: 13
Sum of squares of row 1: 61
Normalized Matrix:
0.277 0.555 0.832
0.512 0.640 0.768

Nested for/while loops and arrays, filtering out numbers from an array

int main(void)
{
int i,j=0,k; //initialization
char equation[100]; //input is a string (I think?)
int data[3]; //want only 3 numbers to be harvested
printf("Enter an equation: ");
fgets(equation, 100, stdin); //not so sure about fgets()
for (i = 0; i < equation[100]+1; i++) { //main loop which combs through
//"equation" array and attempts
//to find int values and store
while (j <= 2) { //them in "data" array
if (isdigit(equation[i])) {
data[j] = equation[i]
j++;
}
}
if (j == 2) break;
}
for (k = 0; k <= 2; k++) { //this is just to print the results
printf("%d\n", data[k]);
}
return 0;
}
Hello! This is my program for my introductory class in C, I am trying to comb through an array and pluck out the numbers and assign them to another array, which I can then access and manipulate.
However, whenever I run this I get 0 0 0 as my three elements in my "data" array.
I am not sure whether I made an error with my logic or with the array syntax, as I am new to arrays.
Thanks in advance!!! :)
There are a few problems in your code:
for (i = 0; i < equation[100]+1; i++) { should be something like
size_t equ_len = strlen(equation);
for (i = 0; i < equ_len; i++) {
Whatever the input is, the value of equation[100] is uncertain, because char equation[100];, equation only has 100 element, and the last of them is equation[99].
equation[i] = data[j]; should be
data[j] = equation[i];
I suppose you want to store digit in equation to data.
break; should be deleted.
this break; statement will jump out of the while loop, the result is you will store the last digit in equation to data[0] (suppose you have switched data and equation, as pointed out in #2).
If you want the first three digits in equation, you should do something like
equ_len = strlen(equation);
j = 0;
for (i = 0; i < equ_len; i++) {
if (j <= 2 && isdigit(equation[i])) {
data[j] = equation[i];
j++;
}
if (j > 2) break;
}
printf("%d\n", data[k]); should be printf("%c\n", data[k]);
%d will give the ASCII code of data[k], for example, if the value of data[k] is character '1', %d will print 50 (the ASCII code of '1') instead of 1.
Here is my final code, based on the OP code:
#include <ctype.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
int i,j,k;
char equation[100];
int data[3];
int equ_len;
printf("Enter an equation: ");
fgets(equation, 100, stdin);
equ_len = strlen(equation);
j = 0;
for (i = 0; i < equ_len; i++) {
if (j <= 2 && isdigit(equation[i])) {
data[j] = equation[i];
j++;
}
if (j > 2) break;
}
for (k = 0; k <= 2; k++) {
printf("%c\n", data[k]);
}
return 0;
}
Tested with:
$ ./a.out
Enter an equation: 1 + 2 + 3
1
2
3

Resources