I'm writing a code to split an array into 2 different ones, one with even numbers and one with odd numbers. I read the numbers from a file, put it all into an array, and get the split right. Here's the code where everything works:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv){
FILE* fpointer;
if (argc >= 2){
fpointer = fopen(argv[1], "r");
}else{
printf("No filename or multiple file names given");
return 0;
}
int numElem;
fscanf (fpointer, "%d\n", &numElem);
printf("Number of elements is %d\n", numElem);
int* arr;
int numEvens;
int numOdds;
arr = (int*) malloc(numElem*sizeof(int));
for (int i = 0; i < numElem; i++){
int temp;
fscanf(fpointer, "%d", &temp);
if(temp%2 == 0){
numEvens++;
}else{
numOdds++;
}
arr[i] = temp;
}
fclose(fpointer);
printf("number of evens: %d \n number of odds: %d\n", numEvens, numOdds);
//The array is now in "arr"
int* evens;
int* odds;
evens = (int*) malloc(numEvens*sizeof(int));
odds = (int*) malloc(numOdds*sizeof(int));
int a = 0;
int b = 0;
for (int i=0; i < numElem; i++){
printf("%d\n", arr[i]);
if (arr[i]%2 == 0){
evens[a] = arr[i];
a++;
}else{
odds[b] = arr[i];
b++;
}
}
printf("EVENS: %d\n", numEvens);
for (int i=0; i < numEvens; i++){
printf("%d\n", evens[i]);
}
printf("ODDS: %d\n", numOdds);
for (int i=0; i < numOdds; i++){
printf("%d\n", odds[i]);
}
Now I have a neat array with even numbers, and one with odd numbers. It outputs numEvens and numOdds correctly. Then I attempt to sort it:
int temp;
int x;
int y;
for (x = 0; x < numEvens-1; x++){
for (y=x+1; y < numEvens; y++){
if (evens[y] < evens[x]){
temp = evens[y];
evens[y] = evens[x];
evens[x] = temp;
}
}
}
return 0;
}
The output before I add in the sort method is:
Number of elements is 8
number of evens: 5
number of odds: 3
25
10
1
99
4
2
8
10
EVENS: 5
10
4
2
8
10
ODDS: 3
25
1
7
And the new output becomes:
Number of elements is 8
number of evens: 32772
number of odds: 1764530596
25
10
1
99
4
2
8
10
EVENS: 32772
10
4
2
8
10
0
0
0
0
....
The 0's go on presumably for another 32,000 times until I abort. I'm trying my hand at C after coming from java so memory allocation is a new subject for me, but I'm assuming it has something to do with that. I just don't understand how variables can be changed by lines of code added in after they are declared and printed. I don't really need help with new sorting methods, I just want some pointers on what's happening here so I can fix the errors. Thanks in advance!
int numEvens;
int numOdds;
Initialize your variables:
int numEvens = 0;
int numOdds = 0;
... and don't cast the result of malloc()!
Related
I'm bad at C pointers, I'm not sure how should I sort the whole array, the code below sorted the array row-wise only, with a warning "assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]". This code sure works in Windows, not sure for other OSes. I am supposed to create a function called snake with 2D const int pointer array, and its size, m as inputs. I am not allowed to move or swap the contents within the array to be scanned, also the whole main function is not allowed to be edited. For example, the input for the whole program is
3
9 8 7
5 4 6
3 2 1
The correct output should be
1 2 3
6 5 4
7 8 9
Instead, I got this
7 8 9
4 5 6
1 2 3
And here is my code. There is a commented section in snake() because the assert function will fail if I uncomment it. I was trying to reverse the even rows (but the index starts from 0, so you can say odd rows also) after sorting.
#include <stdio.h>
#include <assert.h>
void snake(const int *ptr_array[100][100], int m){
int* p =NULL;
int temp;
for(int y=0;y<m;y++){
for(int k=0;k<m-1;k++){
for(int g=0;g<m-k-1;g++){
if(*ptr_array[y][g]>*ptr_array[y][g+1]){
p=(ptr_array[y][g]);
(ptr_array[y][g])=(ptr_array[y][g+1]);
(ptr_array[y][g+1]) = p;
}
}
}
}
// for(int h=1;h<m;h+=2){
// for(int g=0;g<m/2;g++){
// p = (ptr_array[h][m-g]);
// (ptr_array[h][m-g]) = (ptr_array[h][g]);
// (ptr_array[h][g]) = p;
// }
// }
}
int main()
{
int array[100][100], check[100][100];
const int *ptr_array[100][100];
int i, j, m;
scanf("%d", &m);
for (i = 0; i < m; i++){
for (j = 0; j < m; j++) {
ptr_array[i][j] = &(array[i][j]);
scanf("%d", &(array[i][j]));
check[i][j] = array[i][j];
}
}
snake(ptr_array, m);
for (i = 0; i < m; i++) {
for (j = 0; j < m; j++) {
assert(check[i][j] == array[i][j]);
assert((ptr_array[i][j] >= &array[0][0]) && (ptr_array[i][j] <= &array[99][99]));
printf("%d ", *(ptr_array[i][j]));
}
printf("\n");
}
return 0;
}
#include <stdio.h>
void snake(const int *ptr_array[100][100], int m){
int* p =NULL;
int* w=NULL;
int temp,l;
for(int y=0;y<m;y++){
for(int k=0;k<m;k++){
p = ptr_array[y][k];
l = k+1;
for(int g=y;g<m;g++){
while(l<m){
if(*p>*ptr_array[g][l]){
p=(ptr_array[g][l]);
(ptr_array[g][l])=(ptr_array[y][k]);
(ptr_array[y][k]) = p;
}
l++;
}
l=0;
}
}
}
for(int h=1;h<m;h+=2){
for(int g=0;g<=(m-1)/2;g++){
w = (ptr_array[h][m-1-g]);
(ptr_array[h][m-1-g]) = (ptr_array[h][g]);
(ptr_array[h][g]) = w;
}
}
}
I have an int array of size 50 and the first 49 'slots' are filled and I want to move each of the 49 elements of the array one position along so that the first element in the array is now free.
Is there a way to bit shift the entire array 32 bits? like:
array[0] >(49)> 32;
some random made up notation... but I hope it conveys what I am looking for
If you want to take the long way home...
#include <stdio.h>
int main(void)
{
int array_size = 5;
int array[] = {5, 1, 2, 3, 4};
int i;
for (i = array_size - 2; i >= 0; i--)
{
array[i+1] = array[i];
if (i == 0)
array[i] = 0; //whatever you want
}
// not necessary, just print the change
int j;
for (j = 0; j < array_size; j++)
printf("%d ", array[j]);
printf("\n");
return 0;
}
As #COLDSPEED suggested in the comments, memmove does very close to what you are expecting.
void *memmove(void *str1, const void *str2, size_t n)
NOTE: n is the total size in bytes to move. From moving 32 bits you might want to make space for 1 int I guess. (size of int is machine dependent). So, with memmove you can shift 1 byte. Not 1 bit.
And the main purpose of memmove is just to copy. Hence it should not be any better than straight forward copying. Both should take O(n) times.
Conventional method:
for (i = 5; i > 0; i--)
arr[i] = arr[i-1];
arr[0] = 5;
Here is a sample code, using memmove doing the same thing:
#include <stdio.h>
#include <string.h>
int main ()
{
int i;
int arr[5] = {1, 2, 3, 4};
// Printing before state
for (i = 0; i < 4; i++)
printf ("%d ", arr[i]);
printf ("\n");
// The shift operation
memmove(arr+1, arr, 4*sizeof(int));
// Inserting at the beginning
arr[0] = 5;
// Printing after state
printf("After memmove:\n");
for (i = 0; i < 5; i++)
printf ("%d ", arr[i]);
printf ("\n");
return 0;
}
Output:
1 2 3 4
After memmove:
5 1 2 3 4
Here is an article if you want to learn more about mmove: memmove-in-c/c++
Suppose you have a function in C that accepts the dimensions for a 2d array (for simplicity's sake, say for a square nxn array), dynamically allocates the array, then returns it.
I'm aware allocating memory here might be considered somewhat bad practice to begin with, since it will need to be freed elsewhere, but suppose that's not a huge issue. I'm wondering if there's any advantages/disadvantages associated with these two variations of said function:
Variation 1 - Locally define int** variable in function, allocate/return array:
int **create_array(int n) {
// define array pointer, allocate array...
int **a_ = (int**)calloc(n,sizeof(int*));
for (int i = 0; i < n; i++)
a_[i] = (int*)calloc(n,sizeof(int));
return a_;
}
int main() {
int n = 3;
int **array2d = create_array(n)
printf("First element: %d%c",array2d[0][0],'\n');
// do stuff... etc...
}
Variation 2 - Add in-out int** parameter to function, allocate/return array:
int **create_array_2(int **a_, int n) {
// allocate array...
a_ = (int**)calloc(n,sizeof(int*));
for (int i = 0; i < n; i++)
a_[i] = (int*)calloc(n,sizeof(int));
return a_;
}
int main() {
int n = 3;
int **array2d;
array2d = create_array_2(array2d,n);
printf("First element: %d%c",array2d[0][0],'\n');
// do other stuff... etc...
}
Obviously they return the same result and achieve the same task, but is one considered to be safer/more efficient/better practice than the other? In my opinion the 2nd variation just makes things look a bit redundant, but I'm curious if there's any real differences between the two and what happens on the stack/heap when they're called. Hopefully this isn't a dumb question; it's just something I've been curious about. If anyone has insight to share, I'd appreciate it.
I'll probably try to avoid calling malloc and free to many times so this kind of approach is what I'll do:
Example 1:
#include <stdio.h>
#include <stdlib.h>
int *foo(size_t row, size_t col);
int main(void){
int *arr;
unsigned int row, col, k;
printf("Give the ROW: ");
if ( scanf("%u",&row) != 1){
printf("Error, scanf ROW\n");
exit(1);
}
printf("Give the COL: ");
if ( scanf("%u",&col) != 1){
printf("Error, scanf COL\n");
exit(2);
}
arr = foo(row, col);
for (k = 0 ; k < (row * col) ; k++){
printf("%d ",arr[k]);
}
free(arr);
}
int *foo(size_t row, size_t col){
unsigned int i, j;
int *arr = malloc(sizeof *arr * row * col);
int l = 0;
if(arr == NULL){
printf("Error, malloc\n");
exit(3);
}
for ( i = 0; i < row ; i++){
for ( j = 0 ; j < col ; j++){
arr[i * col + j] = l;
l++;
}
}
return arr;
}
Output:
Give the ROW: 6
Give the COL: 3
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Example 2 (if you are working with the standard C):
#include <stdio.h>
#include <stdlib.h>
int (*foo(size_t row, size_t col))[];
int main(void){
size_t row, col;
printf("Give the ROW: ");
if ( scanf("%zu",&row) != 1){
printf("Error, scanf ROW\n");
exit(1);
}
printf("Give the COL: ");
if ( scanf("%zu",&col) != 1){
printf("Error, scanf COL\n");
exit(2);
}
int (*arr)[col] = foo(row, col);
for ( size_t i = 0; i < row; i++){
for( size_t j = 0; j < col; j++){
printf("%d ",*(*(arr+i)+j));
}
}
free(arr);
}
int (*foo(size_t row, size_t col))[]{
int (*arr)[col] = malloc(row * col * sizeof(int));
int l=0;
if (arr == NULL){
printf("Error, malloc\n");
exit(3);
}
for ( size_t i = 0; i < row; i++){
for( size_t j = 0; j < col; j++){
*(*(arr+i)+j) = l;
l++;
}
}
return arr;
}
Output:
Give the ROW: 6
Give the COL: 3
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
The whole point here is that the call of malloc and free in both examples takes place only one time
IMO, of the two you are better off simply returning the value. This way there's a pure and solid wall between you and the caller.
"Give me some stuff!"
"Okay, here's some stuff."
On the other hand, for actually allocating an array of fixed size, why bother with pointers? Why not declare your return type so as to be castable to a sized array?
int (*p2a)[15] = (int(*)[15])create_array_2(15, 15);
Then you would calloc(15*15,sizeof(int)) and be done.
Trying to read an input .txt file with using fscanf, and store the line content to the int variable, array, and 2D array, so I can use the value to do computation later. I think the problem over here is because I did not handle the "EOF" with using fscanf?
Here is my code:
int main(){
FILE *fp;
int n; // # resources
int m; // # processes
int avail[n];
int max[m][n], allo[m][n];
char temp1[10];
fp = fopen("test.txt", "r");
if (fp == NULL){
exit(EXIT_FAILURE);
}
fscanf(fp, "%d %d", &n, &m);
printf("%d %d", n, m);
printf("\n");
// Store the second line content to allo[]
for(int i = 0; i < n; i++){
fscanf(fp, "%s", temp1);
avail[i] = atoi(temp1);
printf("%d ", avail[i]);
}
printf("\n");
// Store the line3-7 content to 2D max[][]
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
fscanf(fp, "%s", temp1);
max[i][j] = atoi(temp1);
printf("%d ", max[i][j]);
}
printf("\n");
}
// Store the line8-12 content to 2D allo
for(int i = 0; i < m; i++){
for(int j = 0; i < n; j++){
fscanf(fp, "%s", temp1);
allo[i][j] = atoi(temp1);
printf("%d ", allo[i][j]);
}
printf("\n");
}
fclose(fp);
return 0;
}
Here is the .txt input file:
3 5
9 6 3
5 5 2
4 1 3
8 3 4
5 4 2
4 4 3
0 1 0
1 1 0
1 0 2
0 0 1
1 2 2
And here is the output:
3 5
9 6 3
5 5 2
4 1 3
8 3 4
5 4 2
4 4 3
Segmentation fault: 11
The problem is here:
int n; // # resources
int m; // # processes
int avail[n];
int max[m][n], allo[m][n], need[n][m];
n and m are not initialized when you declare the 2D array max. Try printing n and m before int max[m][n];, etc. and you will see that they contain garbage values.
As a result, Undefined Behavior is what you are experiencing, since you can't really tell what the size of your array is.
Change it to this:
int n; // # resources
int m; // # processes
fscanf(fp, "%d %d", &n, &m);
printf("%d %d", n, m);
int avail[n];
int max[m][n], allo[m][n], need[n][m];
Now when you create your arrays, n and m will be initialized with the values read from the file.
If you want to declare your arrays before reading n and m, then you should use pointers, read n and m and then dynamically allocate the arrays.
You declare int max[m][n], allo[m][n], need[n][m] while m and n are not set yet, so they are of unknown size. They will not resize themselves after the sizes are set. So writing to these will give you "undefined behaviour"
Since m,n is not initialized when you declared your arrays at the top of your file:
int avail[n];
int max[m][n], allo[m][n], need[n][m];
as #WeatherVane stated in the comments, you will get undefined behavior. Maybe you are overwriting some other part of the programs memory (who knows it is undefined!).
If you need dynamic array creation you should do something like the following:
int* avail;
...
fscanf(fp, "%d %d", &n, &m);
avail = (int*)malloc(n*sizeof(int));
When you initialize max,allo and need. the value of n and m is not defined.
You can define max, allo and need as int**.
After you have scanned the value of n and m, you can invoke the below function to allocate memory for above 2D arrays.
int ** get2DintArray(int r, int c){
int **arr = (int **)malloc(r * sizeof(int *));
for (i=0; i<r; i++)
arr[i] = (int *)malloc(c * sizeof(int));
return arr;
}
For. e.g:-
allo = get2DintArray(m,n);
need = get2DintArray(n,m);
This approach will be handy for higher values of n and m, where the stack memory may not be sufficient, because you are using heap memory in this case.
I want to change rows into column and column into rows of that 2-D array
I want a program which takes input and gives output as below.
Input: 1 2 3
4 5 6
Output: 1 4
2 5
3 6
Input: 1 2 3
4 5 6
7 8 9
Output: 1 4 7
2 5 8
3 6 9
I did a sample which in hardcoded array as below
int main()
{
int i,j;
int grades[2][3] = { {55, 60, 65},
{85, 90, 95}
};
for( j = 0; j < 3; j++)
{
for( i = 0; i < 2;i++)
{
printf("%d\t",grades[i][j]);
}
printf("\n");
}
return 0;
}
Its long time since i programmed in C , is there anyway we can make things dynamic or better way of doing the same. Right now its hardcoded.
I remember we have to use malloc or so , is that right.
psuedo code is also fine.
Taking from Zhehao Mao user and fixing it, the would look like this:
#include <stdio.h>
void transpose(int *src, int *dest, int rows, int cols){
int i,j;
for(i=0; i<rows; i++){
for(j=0; j<cols; j++){
dest[j*rows + i] = src[i*cols + j];
}
}
}
int main(void)
{
int oldar[2][3] = {{1,2,3},{4,5,6}};
int newar[3][2];
transpose(&oldar[0][0], &newar[0][0], 2, 3);
int i, j;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
printf("%d ", oldar[i][j]);
printf("\n");
}
for(i = 0; i < 3; i++)
{
for(j = 0; j < 2; j++)
printf("%d ", newar[i][j]);
printf("\n");
}
}
The reason the original post can't work is that int ** expects a pointer to pointers like:
int **a ---------> int *int1 --> 1
int *int2 --> 2
int *int3 --> 3
which is not what we get when we say int a[n][m]. Rather we have the array organized like this
a[0][0]
\
1 2 3 4 5 6
\___/ \___/
"a[0]" / \____ "a[1]"
or something like this. The picture likely does not explain it well, but currently I can't do better.
void main()
{
clrscr();
int in[10][10];
int out[10][10];
int row,column,i,j;
printf("enter row");
scanf("%d",&row);
printf("Enter column");
scanf("%d",&column);
//storing values in matrix
for(i=1;i<=row;i++)
{
for(j=1;j<=column;j++)
{
printf("Enter (%d,%d)th value",i,j);
scanf("%d",&in[i-1][j-1]);
}
}
//show stored values
printf("\ninput is\n\n");
for(i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
printf("%d\t",in[i][j]);
}
printf("\n");
}
//show transposed value. it is also stored in out matrix
printf("\nOutput is\n\n");
for(i=0;i<column;i++)
{
for(j=0;j<row;j++)
{
printf("%d\t",in[j][i]);
out[i][j]=in[j][i];
}
printf("\n");
}
getch();
}
//////////////////////////////////////
input matrix is stored in in[][] matrix and output matrix stored in out[][] matrix.
this program will work for any matrix with row and column below 10 if we increase the matrix variable value ,it will work for larger matrix also .
Here is a rather naive implementation. I'm pretty sure there are more efficient ways, but this is all I could think of.
void transpose(int **src, int **dest, int rows, int cols){
int i,j;
for(i=0; i<rows; i++){
for(j=0; j<cols; j++){
dest[j][i] = src[i][j];
}
}
}
int main(void){
int oldar[2][3] = {{1,2,3},{4,5,6}};
int newar[3][2];
transpose(oldar, newar, 2, 3);
}
Double pointers can represent double arrays, so there is no need to allocate on the heap here.
This is a half-done program the way I would do it in C:
int main()
{
int **data;
int rows = 0,
columns = 0;
char in[256];
int *irow;
// Get user input.
for(rows = 0; 1; ++rows)
{
scanf("%255s", in);
if(strcmp(in, "exit") == 0)
break;
// Parse row here. Remove all the tabs. Set column count.
for(int icolumn = 0; 1; ++icolumn)
{
/* ... */
}
// Set columns if first time.
if(rows == 0)
columns = icolumn;
// Check to make sure user inputs correct amount of columns.
if(columns != icolumns)
{
printf("OMG! The user is a hacker!\n");
break;
}
// Push parsed row into **data.
data[rows] = irow;
}
// Display output.
for(int i = 0; i < columns; ++i)
{
for(int j = 0; j < rows; ++j)
{
printf("%d\t", data[j][i]);
}
printf("\n");
}
return 0;
}
I'm a C++ programmer, so the user input part is kind of messed up.
hey here is a simple solution without using malloc,i did this when i was on the 0th level for c and had no idea about "alloc.h" functions,
You can have the square array having #rows = #cols = max(#rows,#cols),if we take your example then the matrix would be a 3x3 matrix,then add any special char in the blank entries,so the matrix will look like this
matrix:1 2 3
4 5 6
# # #
now you can easily convert the matrix in the way you want...
Bottom line:To make the matrix operations simpler try to convert them in square matrix...
One more thing using MALLOC is the best possible way ,this is just in case you are not handy with all those alloc.h function defs...
theoretically, you have two arrays
Array x and y
Int grades [x] [y]
you can swap these two arrays and you get
int grades [y] [x]
to do that there are many methods e.g. by copying the arrays to another two 1D, or one 2D Array, or simple Pointer Swap