Could somebody help me with my Code (C language)? - c

I am a beginner in C language and I have been asked to: write a whole program printing in separate lines odd numbers from 100 to 0, and marking with "!!!" those numbers that are multiplications of 7.
I tried to do that but unfortunately iam printing numbers which are duplications for example (91 and 91!!!). How can I avoid this situation?
Here is my code maybe someone can help me with this task?
#include <stdio.h>
int main ()
{
int i;
for (i=100;i>=0;i--)
{
if(i%2)
{
printf("%d\n",i);
}
if (i%7==0 && i%2!=0)
{
printf("%d!!!\n",i);
}
}
}

This is a solution based on Aditi Rawat comment.
#include "stdio.h"
int main ()
{
int i;
for (i=100; i>=0; i--)
{
if (i%7==0 && i%2!= 0)
{
printf("%d!!!\n",i);
}
else
{
if(i%2 != 0)
printf("%d\n",i);
}
}
return 0;
}
OUTPUT:
99
97
95
93
91!!!
89
87
85
83
81
79
77!!!
75
73
71
69
67
65
63!!!
61
59
57
55
53
51
49!!!
47
45
43
41
39
37
35!!!
33
31
29
27
25
23
21!!!
19
17
15
13
1

Related

C return big number confusion

When I input the string instead of y or n in this code, it will return the large number.
So I want to know how to fix it.
My first thought is that if I input the string instead of this,
it will return to the first paragraph and run again.
But when I trying to use this, it will return and run again.
But It will save the string and change it into an ASCII code.
#include <stdlib.h>;
#include <stdio.h>;
int main() {
int num = 1; //設置迴圈變數
int change; //設置可變動變數
int count=0; // 跑了幾次
char ans1,ans2,ans3,ans4,ans5,ans6,ans7 ; //答案共7個
int final_ans = 0;//最後答案
printf("thinking a number on your mind, and I will guess it!\n\n");
first:
for(num=1; num<=100; num+=2) {
++count;
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
count = 0;//清空變數
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans1);
if((ans1=='Y') || (ans1=='y')) { //若有數字
final_ans += 1;
}
second:
for(num=2; num<=100; num+=2) {
change = num;
++count;
if(count%2==0) {
change--;
}
printf("%-4.2d", change);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans2);
count = 0;//清空變數
change = 0;//清空變數
if((ans2=='Y') || (ans2=='y')) {
final_ans += 2;
}
third:
for(num=4; num<=100; num++) {
change = num;
++count;
if(count%4==1&&num!=4) {
num+=4;
}
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans3);
count = 0;//清空變數
change = 0;//清空變數
if((ans3=='Y') || (ans3=='y')) {
final_ans +=4;
}
fourth:
for(num=8; num<=100; num++) {
change = num;
++count;
if(count%8==1&&num!=8) {
num+=8;
}
if(num>100) {
break;
}
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans4);
count = 0;//清空變數
change = 0;//清空變數
if((ans4=='Y') || (ans4=='y')) {
final_ans += 8;
}
fifth:
for(num=16; num<=100; num++) {
change = num;
++count;
if(count%16==1&&num!=16) {
num+=16;
}
if(num>100) {
break;
}
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans5);
count = 0;//清空變數
change = 0;//清空變數
if((ans5=='Y') || (ans5=='y')) {
final_ans += 16;
}
sixth:
for(num=32; num<=100; num++) {
change = num;
++count;
if(count%32==1&&num!=32) {
num+=32;
}
if(num>100) {
break;
}
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans6);
count = 0;//清空變數
change = 0;//清空變數
if((ans6=='Y') || (ans6=='y')) {
final_ans += 32;
}
seventh:
for(num=64; num<=100; num++) {
++count;
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans7);
if((ans7=='Y') || (ans7=='y')) {
final_ans += 64;
}
else if((ans1=='n') || (ans1=='N')) { //若無數字
final_ans += 0;
goto second;//回到第二個table
} else if((ans2=='n') || (ans2=='N')) { //若無數字
final_ans += 0;
goto third;//回到第三個table
} else if((ans3=='n') || (ans3=='N')) { //若無數字
final_ans += 0;
goto fourth;//回到第四個table
} else if((ans4=='n') || (ans4=='N')) { //若無數字
final_ans += 0;
goto fifth;//回到第五個table
} else if((ans5=='n') || (ans5=='N')) { //若無數字
final_ans += 0;
goto sixth;//回到第六個table
} else if((ans6=='n') || (ans6=='N')) { //若無數字
final_ans += 0;
goto seventh;//回到第七個table
} else if((ans7=='n') || (ans7=='N')) { //若無數字
final_ans += 0;
}
if(final_ans<=100) { //判斷最後答案
printf("your secret number is %d",final_ans);
} else if(final_ans>100) {
printf("WRONG!%d is not a number form 1~100",final_ans);
}
}
you have put ; after every library please remove that
#include <stdlib.h>; // remove the ;
#include <stdio.h>; // remove the ;
correct code must be
#include <stdlib.h>
#include <stdio.h>
By editing that I got correct answers. it works for me.
I have think about 73
output -:
thinking a number on your mind, and I will guess it!
01 03 05 07 09 11 13 15 17
19 21 23 25 27 29 31 33 35
37 39 41 43 45 47 49 51 53
55 57 59 61 63 65 67 69 71
73 75 77 79 81 83 85 87 89
91 93 95 97 99
Is your number on the table (y/n)?
y
02 03 06 07 10 11 14 15 18
19 22 23 26 27 30 31 34 35
38 39 42 43 46 47 50 51 54
55 58 59 62 63 66 67 70 71
74 75 78 79 82 83 86 87 90
91 94 95 98 99
Is your number on the table (y/n)?
n
04 05 06 07 12 13 14 15 20
21 22 23 28 29 30 31 36 37
38 39 44 45 46 47 52 53 54
55 60 61 62 63 68 69 70 71
76 77 78 79 84 85 86 87 92
93 94 95 100
Is your number on the table (y/n)?
n
08 09 10 11 12 13 14 15 24
25 26 27 28 29 30 31 40 41
42 43 44 45 46 47 56 57 58
59 60 61 62 63 72 73 74 75
76 77 78 79 88 89 90 91 92
93 94 95
Is your number on the table (y/n)?
y
16 17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 48 49
50 51 52 53 54 55 56 57 58
59 60 61 62 63 80 81 82 83
84 85 86 87 88 89 90 91 92
93 94 95
Is your number on the table (y/n)?
n
32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58
59 60 61 62 63 96 97 98 99
100
Is your number on the table (y/n)?
n
64 65 66 67 68 69 70 71 72
73 74 75 76 77 78 79 80 81
82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99
100
Is your number on the table (y/n)?
n
64 65 66 67 68 69 70 71 72
73 74 75 76 77 78 79 80 81
82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99
100
Is your number on the table (y/n)?
y
your secret number is 73

Odd behavior in my code for a certain test case

The program is supposed to swap neighbouring elements which don't have a common denominator, and an element can only be swapped once.
When i run the program, pretty much for any input works fine. Except for this one:
100 //input for number of elements
48 92 76 93 17 38 59 34 53 99 58 20 50 0 38 37 16 36 91 12 59 1 76 82 20 76 7 72 13 70 64 23 81 70 41 69 11 0 16 41 37 83 41 99 73 79 4 38 24 32 87 38 95 24 77 30 61 13 89 67 87 76 22 31 67 31 25 90 6 76 21 43 40 55 72 91 91 28 18 58 72 71 83 22 99 23 86 58 75 53 69 29 5 55 46 8 98 55 19 46 //the elements
For this input, the program hangs and prints nothing. Does someone know what is going on in this particular case?
#include <stdio.h>
int nzd(int a, int b)
{
if(a==b || b==0)
return a;
if(a>b)
return nzd(a-b, b);
return nzd(a, b-a);
}
int swap(int *niza, int i)
{
int temp;
temp=*(niza+i);
*(niza+i)=*(niza+i+1);
*(niza+i+1)=temp;
}
int main()
{
int a[100], n, i;
scanf("%d", &n);
for(i=0; i<n; i++)
{
scanf("%d", &a[i]);
}
for(i=0; i<n; i++)
{
if(i+1==n) continue;
if(nzd(a[i], a[i+1])==1)
{
swap(a, i);
i++;
}
}
for(i=0; i<n; i++)
{
printf("%d ", a[i]);
}
return 0;
}
Your gcd function checks for the case of b==0 but not the case for a==0. Because you skip that check, you end up calling nzd(0, b-0); which is exactly the same as the prior call. This puts you in an infinite recursion loop which will eventually cause a stack overflow.
Add the check for this case in your function:
if(a==b || b==0 || a == 0)
Also, a faster implementation of gcd, called Euclid's algorithm, is as follows:
int gcd(int a, int b)
{
if (b==0) {
return a;
} else {
return (b, a%b);
}
}
Your function nzd() fails to handle the case a == 0 correctly and gets stuck in an endless loop. You need to handle this case, too:
int nzd(int a, int b)
{
if(a==b || a==0 || b==0)
return a;
if(a>b)
return nzd(a-b, b);
return nzd(a, b-a);
}

What's wrong with the matrix?

What's wrong with this code?
My task is: Create a square matrix of integers with a size of 9x9. Fill the matrix with random numbers. Display the main and side diagonal symmetrically with respect to the vertical axis. The example of expected result is here: matrix
Matrix :
20 20 76 65 93 76 16 2 85
6 87 78 43 48 81 71 90 38
10 12 35 77 48 88 24 53 7
12 66 51 35 74 7 30 22 49
58 14 71 46 68 68 10 81 51
98 16 74 47 64 25 17 30 37
2 44 44 74 34 54 86 73 28
85 4 57 75 18 28 51 76 2
35 17 53 76 15 91 83 85 72
The main and side diagonal:
85 20 76 65 93 76 16 2 20
6 90 78 43 48 81 71 87 38
10 12 24 77 48 88 35 53 7
12 66 51 7 74 35 30 22 49
58 14 71 46 68 68 10 81 51
98 16 74 25 64 47 17 30 37
2 44 86 74 34 54 44 73 28
85 76 57 75 18 29 51 4 2
72 17 53 76 15 91 83 85 35
But in fact the program prints only the main matrix with random numbers and after that stops.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <Windows.h>
int main()
{
int a = 9;
int matrix[a][a];
int temp;
int i, j, n;
srand((unsigned)time(NULL));
printf("Matrix : \n\n");
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
matrix[i][j] = rand() % 100;
printf("%d\t", matrix[i][j]);
}
printf("\n\n");
}
printf("The main and side diagonal:\n\n");
for (i = 0; i < a; ++i) {
temp = matrix[i][i];
matrix[i][i] = matrix[i][(a - 1) - i];
matrix[i][(a - 1) - i] = temp;
}
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result:", matrix[i][j]);
printf("\n\n\n");
system("pause");
return 0;
}
}
}
You are returning where you are not supposed to. (in middle of the calculation). You should return after you end up working on the for loops.
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result:", matrix[i][j]); <--- Not printing element
printf("\n\n\n");
system("pause");
return 0; <-----
}
}
It should be
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result: %d ", matrix[i][j]); <----You forgot the
//format specifier
printf("\n\n\n");
system("pause");
}
}
return 0;<-----
Readability is hampered when the indentation is like this. You implemented wrong logic out of it.
OP asks that it stops after printing "Result" that is because you forgot to put the format specifier in the code. That's why none of the element is printed.
Op wants to print the main and side diagonal symmetrically with respect to the vertical axis.
Now this is everything to with the print part.
Now we have to find a way that will let us distinguish which one is diagonal element and which one is not.
Suprisingly the answer should be known to someone who is writing the previous swapping logic. (Though it is not clear why OP swapped it).
Now all element matrix[p][q] will be from either diagonal if p=q or p+q=a-1. (Note that matrix is a square matrix).
But OP meant to print the matrix
for (i = 0; i < a; ++i) {
if( i == 0) printf("The main and side diagonal : \n");
for (j = 0; j < a; ++j) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
}
Use functions. You print the matrix twice; you should have a function to print the matrix which you call twice.
With such a function, you'd not make the mistakes in the tail end of your code. For example, you could use this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static void print_matrix(const char *tag, int size, int matrix[size][size])
{
printf("%s (%dx%d):\n\n", tag, size, size);
for (int i = 0; i < size; ++i)
{
const char *pad = "";
for (int j = 0; j < size; ++j)
{
printf("%s%-2d", pad, matrix[i][j]);
pad = " ";
}
printf("\n\n");
}
}
int main(int argc, char **argv)
{
unsigned seed = time(0);
int a = 9;
int matrix[a][a];
if (argc == 2)
seed = atoi(argv[1]);
srand(seed);
printf("Seed: %u\n", seed);
for (int i = 0; i < a; ++i)
{
for (int j = 0; j < a; ++j)
matrix[i][j] = rand() % 100;
}
print_matrix("Matrix", a, matrix);
for (int i = 0, j = a - 1; i < a; ++i, --j)
{
int temp = matrix[i][i];
matrix[i][i] = matrix[i][j];
matrix[i][j] = temp;
}
print_matrix("The main and side diagonal", a, matrix);
return 0;
}
The code reports the seed it uses; that allows you to reproduce any run by specifying the seed to use as a command line argument.
Example output:
Seed: 1511470282
Matrix (9x9):
11 39 3 88 98 63 75 81 76
93 9 60 22 45 50 46 58 65
13 99 25 43 14 57 44 70 65
30 57 55 0 37 84 47 49 40
60 28 46 1 96 78 33 20 9
93 61 11 38 84 16 91 26 15
43 85 66 72 85 39 96 45 45
45 25 33 3 78 90 61 65 62
88 84 56 34 74 8 78 57 74
The main and side diagonal (9x9):
76 39 3 88 98 63 75 81 11
93 58 60 22 45 50 46 9 65
13 99 44 43 14 57 25 70 65
30 57 55 84 37 0 47 49 40
60 28 46 1 96 78 33 20 9
93 61 11 16 84 38 91 26 15
43 85 96 72 85 39 66 45 45
45 65 33 3 78 90 61 25 62
74 84 56 34 74 8 78 57 88
The swapping process, in case it isn't obvious, swaps the first and last elements of the first row, the second and last but one element in the second row, and so on, forming an X of swapped elements.

Suggestion about unique values generation

I want to generate a series of "random" unique numbers, for use at a card game! These numbers should be between 0 and 81.
I don't care about security or speed at this stage, i just want something simple to have the work done.
In my code below, i have managed to create 2 unique random numbers in the array that holds them, but the rest 10 numbers don't change but stay -1 that was the initial value..
I have found more accurate ways for random number generation, but i will check them out at a later stage!
#include <stdio.h>
#include <stdlib.h>
int getRandomNumber(int Min, int Max)
{
double rnd= (double)rand()/((double)RAND_MAX+1);
return (int)(rnd*(Max-Min+1))+Min;
}
int main()
{
int j,counter,temp,deck[13];
srand(time(NULL));
int i;
counter=1;
for (i=0;i<12;i++)
{deck[i]=-1;
temp = getRandomNumber(0,81);
for (j=0;j<=i;j++)
{if (temp==deck[j])
{counter=0;}
if (counter!=0)
deck[i]=temp;
}
}
for(i=0;i<12;i++)
printf("%d ",deck[i]);
}
Your code has one of the weirder indentation and brace layout schemes I've ever seen:
#include <stdio.h>
#include <stdlib.h>
int getRandomNumber(int Min, int Max)
{
double rnd= (double)rand()/((double)RAND_MAX+1);
return (int)(rnd*(Max-Min+1))+Min;
}
int main()
{
int j,counter,temp,deck[13];
srand(time(NULL));
int i;
counter=1;
for (i=0;i<12;i++)
{deck[i]=-1;
temp = getRandomNumber(0,81);
for (j=0;j<=i;j++)
{if (temp==deck[j])
{counter=0;}
if (counter!=0)
deck[i]=temp;
}
}
for(i=0;i<12;i++)
printf("%d ",deck[i]);
}
Converted to a more orthodox style (Allman, more or less — see Wikipedia on Indent style), you get:
#include <stdio.h>
#include <stdlib.h>
static int getRandomNumber(int Min, int Max)
{
double rnd = (double)rand() / ((double)RAND_MAX + 1);
return (int)(rnd * (Max - Min + 1)) + Min;
}
int main(void)
{
int j, counter, temp, deck[13];
srand(time(NULL));
int i;
counter = 1;
for (i = 0; i < 12; i++)
{
deck[i] = -1;
temp = getRandomNumber(0, 81);
for (j = 0; j <= i; j++)
{
if (temp == deck[j])
{
counter = 0;
}
if (counter != 0)
deck[i] = temp;
}
}
for (i = 0; i < 12; i++)
printf("%d ", deck[i]);
}
The static and int main(void) are needed to get the code past my default compilation options; otherwise, they're cosmetic.
Now we can see some problems. The counter is set to 1 once, outside the outer loop; it is set to 0 sometimes inside the loop, but once that happens, it is never reset to 1, so no further numbers are added to the deck. You need to rework the inner loop, maybe like this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static int getRandomNumber(int Min, int Max)
{
double rnd = (double)rand() / ((double)RAND_MAX + 1);
return (int)(rnd * (Max - Min + 1)) + Min;
}
int main(void)
{
int deck[13];
srand(time(NULL));
for (int i = 0; i < 12; i++)
{
int temp = getRandomNumber(0, 81);
deck[i] = -1;
int counter = 1;
for (int j = 0; j <= i; j++)
{
if (temp == deck[j])
{
counter = 0;
break;
}
}
if (counter != 0)
deck[i] = temp;
else
i--; // Try again with a new random choice for the same i
}
const char *pad = "";
for (int i = 0; i < 12; i++)
{
printf("%s%d", pad, deck[i]);
pad = " ";
}
putchar('\n');
return 0;
}
I dislike trailing blanks, so the printing loop takes care to ensure there aren't any.
Sample output with getRandomNumber() — on macOS Sierra 10.12.2 with GCC 6.3.0:
7 73 38 61 11 13 41 66 29 39 72 20
7 2 18 17 54 31 45 40 34 22 63 16
7 13 80 54 16 49 14 58 28 53 23 26
7 24 60 10 67 53 69 32 23 2 66 12
7 34 40 48 21 3 57 43 6 18 27 80
7 45 20 3 65 21 61 17 12 69 66 27
7 67 62 78 70 57 68 46 9 2 72 39
7 77 41 34 32 75 72 20 64 78 33 25
7 6 21 72 76 11 75 38 73 27 64 33
7 17 1 27 37 28 80 49 12 67 59 36
That first number isn't very random — shortly after that sequence of tests, it changed from 7 to 8, but was equally non-random. An alternative
way of generating random numbers is:
static int getRandomNumber(int Min, int Max)
{
int rnd;
int range = (Max - Min + 1);
while ((rnd = rand()) > RAND_MAX - (RAND_MAX % range))
;
return (rnd % range) + Min;
}
This avoids the bias from that fact that 82 doesn't divide RAND_MAX exactly, which would weight the distribution of the lower numbers slightly higher than the upper numbers in the range 0..81. It also avoids the unexpectedly consistent first number, though the new first number is also semi-predictable when the tests are run at 1-second intervals.
Sample results:
48 33 28 78 14 2 81 13 23 75 38 40
45 42 74 1 11 68 17 33 78 49 23 80
42 51 38 3 5 52 35 56 54 23 59 41
39 60 2 8 36 53 79 30 72 75 62 37
36 69 45 10 78 20 71 17 6 53 54 30
33 78 9 15 75 7 40 61 27 36 70 68
30 5 55 17 69 73 25 63 37 1 21 71
27 14 19 66 57 43 1 13 3 65 71 21
24 26 62 63 41 61 68 28 67 20 74 17
21 35 26 57 28 79 47 44 2 52 60 77
Notice that the first number decreases by 3; the second seems to increase by 9; ugh — the randomness isn't all that good. It's well known that rand() is often not a high quality PRNG (pseudo-random number generator), but I'm a little surprised by this apparently systematic behaviour with seeds that differ by 1 each time.
On my Mac, when I changed srand() to srandom() and rand() to random(), I got better (as in, more unpredictable) results:
29 1 7 11 25 52 63 15 26 55 75 64
40 4 64 18 8 57 73 27 38 15 60 28
43 3 27 17 1 58 26 72 73 18 20 7
76 16 27 43 64 20 63 30 35 17 33 57
79 47 32 33 6 30 35 7 38 55 25 61
69 57 79 75 15 54 5 35 21 46 65 61
30 79 66 14 56 39 19 8 50 47 76 33
62 65 81 44 52 39 25 30 54 12 24 68
27 49 60 72 53 35 14 41 63 46 45 65
67 39 9 11 60 19 64 73 43 17 21 26
And the Mac man page for random() still suggests using arc4random() instead, but this is a lot better than plain rand(). What you find on other systems will depend on the facilities provided by the system — rand() may not be as awful as it seems to be on Mac. Basically, be cautious with your choice of PRNG — especially if you're going to use systematically generated seeds (such as the current time).
For the purpose you propose (generating a random sequence of numbers ranging from 0 through 81, where each item differs from the others), you will need a particular kind of random number generator (RNG), one that can generate all possible permutations of 82 items (expressed as 82!, or 82 factorial). However, only a limited selection of RNGs can do this. In particular the C rand() function's implementation is unspecified, so is not guaranteed to generate that many permutations.
A pseudorandom number generator (PRNG, a kind of RNG as used here) can't generate more random number sequences than its period. For 82! permutations, no PRNG with a period less than 82! can do this (the next highest power of 2 is 2408, meaning the generator needs to takes a seed at least 408 bits, or 51 bytes, long for it to possibly do so -- and 51 bytes is much bigger than srand can usually take). Alternatively, for this purpose, you would be well advised to use an RNG that generates "unpredictable" numbers, which neither the C language nor the C library includes as standard. See "Shuffling" and "Unpredictable RNGs" in my article on randomness for more information.

Partial Threaded Sorting in C

I'm trying to do a partial sort with a threads,
my current output it
27 12 21 48 15 28 82 69 35 91
13 82 33 35 46 5 35 28 87 95
0 10 20 22 23 30 52 80 86 96
3 8 42 53 67 70 70 71 75 79
5 8 8 18 41 43 70 79 86 88
10 51 56 60 65 84 87 91 94 99
23 25 38 39 40 44 51 56 69 75
20 21 25 29 29 38 66 71 73 96
33 50 9 6 13 27 97 21 70 22
3 4 6 6 7 15 34 59 63 70
As you can see I am getting it partially sorted I want my output to be this (no merging at the end)
12 15 21 27 28 35 48 69 82 91
5 13 28 33 35 35 46 82 87 95
0 10 20 22 23 30 52 80 86 96
3 8 42 53 67 70 70 71 75 79
5 8 8 18 41 43 70 79 86 88
10 51 56 60 65 84 87 91 94 99
23 25 38 39 40 44 51 56 69 75
20 21 25 29 29 38 66 71 73 96
6 9 13 21 22 27 33 50 70 97
3 4 6 6 7 15 34 59 63 70
I can get the right output if instead of using a struct I use &array[i] and manually input the length
This is the code I have so far:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pthread.h>
int cmpfunc(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
struct values {
int *arrayptr;
int length;
};
void *thread_fn(void *a) {
struct values *start = a;
qsort(start->arrayptr, start->length, sizeof(int), cmpfunc);
return (void*)a;
}
int main(int argc, const char *argv[]) {
FILE *fp = fopen(argv[3], "r");
FILE *fp1 = fopen("numS1.dat", "w+");
//amount of threads
int threadAmount = atoi(argv[1]);
//size of input
int numberAmount = atoi(argv[2]);
//multidimensional array
int array[threadAmount][numberAmount / threadAmount];
for (int i = 0; i < threadAmount; i++)
for (int j = 0; j < numberAmount / threadAmount; j++)
fscanf(fp, "%d", &array[i][j]);
pthread_t threadid[threadAmount];
for (int i = 0; i < threadAmount; ++i) {
struct values a = { array[i], numberAmount / threadAmount };
pthread_create(&threadid[i], NULL, thread_fn, &a);
}
for (int i = 0; i < threadAmount; ++i)
pthread_join(threadid[i], NULL);
for (int i = 0; i < threadAmount; i++) {
if (i != 0)
fprintf(fp1, "\n");
for (int j = 0; j < numberAmount / threadAmount; j++)
fprintf(fp1 ,"%d ", array[i][j]);
}
return 0;
}
Do you know where I am going wrong?
I think its the struct but everything I see online does what I'm doing.
You are passing a pointer to automatic storage to newly created threads: the struct values object becomes invalid as soon as the calling scope is exited, thus it cannot be reliably accessed by the new thread. You should allocate the struct values and pass the pointer to the allocated object as a parameter to pthread_create:
for (int i = 0; i < threadAmount; ++i) {
struct values *a = malloc(sizeof(*a));
a->arrayptr = array[i];
a->length = numberAmount / threadAmount;
pthread_create(&threadid[i], NULL, thread_fn, a);
}
The structure can be freed by the thread function before exiting.
Notes:
the way you split the array into chunks only works if the length is a multiple of the number of threads.
the comparison function does not work for large int values, you should use this instead:
int cmpfunc(const void *a, const void *b) {
return (*(int*)b < *(int*)a) - (*(int*)a < *(int*)b);
}

Resources