I'm facing an issue where my code seems to misbehave - the cursor is blinking in the terminal, but the code isn't responding, it's stuck.
I tried to do some debugging, but couldn't figure out what's causing it to happen.
Here's my code:
#include <stdio.h>
int main()
{
int prim[20]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71},szam,i=0;
printf("Kerek egy szamot!\n");
scanf("%d",&szam);
while(szam!=1)
{
if(szam%prim[i]==0)
{
szam=szam/prim[i];
printf("%d*",prim[i]);
}
else
{
if(szam%prim[i]!=0)
{
prim[i]=prim[i+1];
}
}
}
printf("1");
return 0;
}
Basically, what it should do for an integer input is (as the title suggests integer factorization).
I went through various inputs on a sheet and checked what would happen according to my code.
For input = 40 it should execute the first while loop, then step into the if clause, then get divided by 2, and output 2*. Skip the else part and enter the while loop again since 20 not equals with 1. Again, should get divided by 2, and output another 2*, repeat the same process one more time, by now outputting 2*2*2*, and for the 4th iteration, it should enter the else clause, as the input has reduced to 5. Then execute the if clause, increase value of "i" by 1, and since the value of the input should remain 5, iterate the else clause again. Then increase the value of "i" by 1 again, which points to the third element of the array by now, which is 5. Now that both values are the same (input and "i"), it should do the first if clause one more time and output 2*2*2*5*1.
The code is never showing the requested 1 before the return 0;, which makes me think it gets stuck inside the while loop.
Any help is highly appreciated.
Thank you in advance.
There are multiple problems with Revision 1 of the self-answer. These include:
You should not be editing the prim array, but your else clause changes it. Make that const int prim[] = { … };. For a single-cycle program, that doesn't matter, but if you tried to create a loop so as to analyze multiple numbers in a single run, modifying the prim array means that it can't be reused on the next cycle unless it is initialized, but the first 20 primes don't change so you really shouldn't be modifying it at all.
Also, prim[i] = prim[i++]; is UB — you use i twice and modify it, and the sequencing is not defined.
You need to use i++ rather than the assignment, but you also need to ensure that i does not go out of bounds of the array.
Here's a mildly modified version of your code — it prints the prim array to show the damage done.
#include <stdio.h>
static void dump_array(const char *tag, size_t size, const int array[size])
{
printf("%s (%zu):\n", tag, size);
const char *pad = "";
for (size_t i = 0; i < size; i++)
{
printf("%s%d", pad, array[i]);
pad = " ";
}
putchar('\n');
}
int main(void)
{
int prim[20] =
{
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
};
int szam, i = 0;
dump_array("Primes before", sizeof(prim)/sizeof(prim[0]), prim);
printf("Kerek egy szamot!\n");
scanf("%d", &szam);
while (szam != 1)
{
if (szam % prim[i] == 0)
{
szam = szam / prim[i];
printf("%d*", prim[i]);
}
else
{
prim[i] = prim[i + 1];
i++;
}
}
printf("1\n");
dump_array("Primes after", sizeof(prim)/sizeof(prim[0]), prim);
return 0;
}
This produces correct outputs on some inputs. The source was in pr53.c and the program was pr53:
$ pr53
Primes before (20):
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
Kerek egy szamot!
48
2*2*2*2*3*1
Primes after (20):
3 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
$ pr53
Primes before (20):
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
Kerek egy szamot!
47
47*1
Primes after (20):
3 5 7 11 13 17 19 23 29 31 37 41 43 47 47 53 59 61 67 71
$ pr53
Primes before (20):
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
Kerek egy szamot!
46
2*23*1
Primes after (20):
3 5 7 11 13 17 19 23 23 29 31 37 41 43 47 53 59 61 67 71
$ pr53
Primes before (20):
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
Kerek egy szamot!
165
3*5*11*1
Primes after (20):
3 5 7 11 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
$
So far, so good. Note that the code handles numbers bigger than 71 as long as the biggest prime factor is no larger than 71.
If the code reused the prim array, the factor 2 has been lost. Over time, other factors would be lost too — the analysis would no longer be correct.
However, the behaviour is less than satisfactory when the number entered has a prime factor larger than 71:
$ pr53
Primes before (20):
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
Kerek egy szamot!
73
Floating point exception: 8
$
It is not very hard to write code that handles such range errors better. For example, consider this program (source pr71.c, program pr71). Since the array of primes is constant, there's no need to print it; it doesn't change. I also print 1 first so that the factors are consistently increasing. At the end, the code prints szam if it is not 1, and adds a newline.
#include <stdio.h>
int main(void)
{
const int prim[20] =
{
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
};
enum { NUM_PRIM = sizeof(prim) / sizeof(prim[0]) };
int szam;
printf("Kerek egy szamot!\n");
if (scanf("%d", &szam) != 1)
return 1;
int i;
printf("1");
for (i = 0; i < NUM_PRIM && szam > 1; i++)
{
while (szam % prim[i] == 0)
{
szam = szam / prim[i];
printf("*%d", prim[i]);
}
}
if (szam > 1)
printf("*%d", szam);
putchar('\n');
return 0;
}
Example runs:
pr71
Kerek egy szamot!
48
1*2*2*2*2*3
LP2-US-51694112 JL: pr71
Kerek egy szamot!
47
1*47
LP2-US-51694112 JL: pr71
Kerek egy szamot!
46
1*2*23
$ pr71
Kerek egy szamot!
73
1*73
$ pr71
pr71
Kerek egy szamot!
166
1*2*83
$ pr71
Kerek egy szamot!
5329
1*5329
$
Only the last result is incorrect; 5329 is 73², so it is composite.
One of the many tests I ran processed the numbers in the range 5300..5330, and pr71 produced the filtered output:
1*2*2*5*5*53
1*3*3*19*31
1*2*11*241
1*5303
1*2*2*2*3*13*17
1*5*1061
1*2*7*379
1*3*29*61
1*2*2*1327
1*5309
1*2*3*3*5*59
1*47*113
1*2*2*2*2*2*2*83
1*3*7*11*23
1*2*2657
1*5*1063
1*2*2*3*443
1*13*409
1*2*2659
1*3*3*3*197
1*2*2*2*5*7*19
1*17*313
1*2*3*887
1*5323
1*2*2*11*11*11
1*3*5*5*71
1*2*2663
1*7*761
1*2*2*2*2*3*3*37
1*5329
1*2*5*13*41
This agrees with the output from another program factoring the same range — except for the second last line where 5329 is properly factored:
5300: (2^2).(5^2).53
5301: (3^2).19.31
5302: 2.11.241
5303: 5303
5304: (2^3).3.13.17
5305: 5.1061
5306: 2.7.379
5307: 3.29.61
5308: (2^2).1327
5309: 5309
5310: 2.(3^2).5.59
5311: 47.113
5312: (2^6).83
5313: 3.7.11.23
5314: 2.2657
5315: 5.1063
5316: (2^2).3.443
5317: 13.409
5318: 2.2659
5319: (3^3).197
5320: (2^3).5.7.19
5321: 17.313
5322: 2.3.887
5323: 5323
5324: (2^2).(11^3)
5325: 3.(5^2).71
5326: 2.2663
5327: 7.761
5328: (2^4).(3^2).37
5329: (73^2)
5330: 2.5.13.41
Thank you very much for the replies! I didn't know the increment could never be done by "+1". I applied your suggestions, and it works as wanted.
#include <stdio.h>
int main()
{
int prim[20]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71},szam,i=0;
printf("Kerek egy szamot!\n");
scanf("%d",&szam);
while(szam!=1)
{
if(szam%prim[i]==0)
{
szam=szam/prim[i];
printf("%d*",prim[i]);
}
else
{
prim[i]=prim[i++];
}
}
printf("1");
return 0;
}
I am able to print out a 2D array into an output file but it is not uniform. I would like to have the 2D array evenly spaced when it is printed out. I am fairly new at programing in C so any help would be greatly appreciated!
My Code:
#include <stdio.h>
#include <stdlib.h>
/**
* Driver method for program
*/
int main()
{
int nums[200];
int i = 0;
int j = 0;
FILE * in_file;
FILE * out_file;
srand(time(0)); //seed for random generator
/**
* if loop reads text file and stores numbers into array
*/
if (in_file = fopen("Data.txt", "r")) {
while (fscanf(in_file, "%d", &nums[i]) != EOF) {
i++;
}
int numbsinfile = i;
int random = randomNumber(2, 12);
int matrix1[5][random];
int matrix2[random][5];
out_file = fopen("out.txt", "w");
fprintf(out_file, "Matrix 1: \n");
fprintf(out_file, "Rows = 5 \n");
fprintf(out_file, "Columns = %d \n\n", random);
for(i = 0; i < 5; i++ ){
for(j = 0; j < random; j++){
int rand = randomNumber(0, numbsinfile);
matrix1[i][j] = nums[rand];
fprintf(out_file, "%d \t\t", matrix1[i][j]);
}
fprintf(out_file, "\n");
}
fclose(in_file);
fclose(out_file);
}
return 0;
}
/**
* Generates and prints random
* numbers in range [lower, upper].
*/
int randomNumber(int lower, int upper) {
int num = (rand() % (upper - lower + 1)) + lower;
return num;
}
The input file I am using along with the output file that my code produces. I am basically just wanting to clean up the 2D array that is printed to the output file.
input file:
23 34 -54 21 45 34 65 -54 21 45 34 65 -34 24 58
49 45 10 -57 20
57 39 20 58 23 10 20 58 -60 76 -82 28
28 -37 49 358 47 -50 37 29
57 -29 -20 47 69
93 57 23 49 -38 49 27 -40 48 39
56 -30 47 28 49
37 49
27 26 10 20 58 -60 26 10 20 58 -60 76 -82 28
28 -37 49 -28 93 28
73 47 27 83 37 -29 40 37 49 20
17 -26 12 17 17
18 38 29 39 -118
19 10 20 58 -60 76 -82 28
28 -37 49 59 10 58 -60 76 -82 28
28 -37 49 59 10 20 58 -60 76 -82 28
28 -37 49 30 -58 58 38 49 30 -58 58 38
49 30 -58 58 38
28 39
39 48 23 -50 28
48 29 39 40 29
My output file:
Matrix 1:
Rows = 5
Columns = 12
28 39 20 49 58 76 37 -26 47 -40 216309856 26
57 -50 30 47 29 58 73 20 26 216309856 49 26
216309856 30 59 45 20 23 -50 83 -50 -37 28 30
10 10 23 28 47 45 34 10 19 -38 -118 28
47 49 -40 20 49 29 10 20 58 69 10 28
How to print a “neat” 2D array in C (?)
Find the longest text width using snprintf(NULL, 0, some_format, ...
int width = 1;
for(i = 0; i < 5; i++ ) {
for(j = 0; j < random; j++) {
int rand = randomNumber(0, numbsinfile);
matrix1[i][j] = nums[rand];
int w = snprintf(NULL, 0, "%d", matrix1[i][j]);
if (w > width) width = w;
}
}
Use * in the specifier and width for printing.
for(i = 0; i < 5; i++ ) {
for(j = 0; j < random; j++) {
fprintf(out_file, " %*d", width, matrix1[i][j]);
}
fprintf(out_file, "\n");
}
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.
Before you say, yes I've checked nearly all the other postings, none are working.
My program has been giving me a segmentation error for hours and hours and nothing is fixing it. I debugged it to the point where I found it's in the file pointer. From what I know, it's because of the way I'm either using the file pointer in the 'makeArray' function or from the file closing statement. I don't really understand how it's not working because I used my last program as reference for this and it runs perfectly fine but this one won't.
#include <stdio.h>
#include <stdlib.h>
#define ROWS 12
#define COLS 8
void makeArray(FILE*, int [][COLS]);
int getScore(int [][COLS], int, int);
int getMonthMax(int [][COLS], int);
int getYearMax(int [][COLS]);
float getMonthAvg(int [][COLS], int);
float getYearAvg(int [][COLS]);
int toursMissed(int [][COLS]);
void displayMenu();
int processRequest(int [][COLS], int);
void printArray(int [][COLS]);
int main(){
int scoresArray[ROWS][COLS];
int choice, constant = 0;
FILE* inputPtr;
inputPtr = fopen("scores.txt", "r");
makeArray(inputPtr, scoresArray);
fclose(inputPtr);
while(constant == 0){
displayMenu();
scanf("%d", &choice);
processRequest(scoresArray, choice);
}
return 0;
}
void makeArray(FILE* inputPtr, int scoresArray[][COLS]){
int i, j;
for(i = 0; i < ROWS; i++){
for(j = 0; j < COLS; j++){
fscanf(inputPtr, "%d", &scoresArray[i][j]);
}
}
return;
}
I've tried moving the file pointers to every different spot in the code and nothing. I don't necessarily want you to just give me the answer but I want an explanation of why it's happening in this specific code because every other post I've checked and their results don't match up to mine.
Also the input file is
26 35 25 92 0 6 47 68 26 72 67 33 84 28
22 36 53 66 23 86 36 75 14 62 43 11 42 5
14 58 0 23 30 87 80 81 13 35 94 45 1 53
14 55 46 19 13 0 25 28 66 86 69 0 81 15
55 60 26 70 22 36 15 67 62 16 71 7 29 92
84 37 2 30 7 5 4 50 0 67 2 53 69 87
8 23 74 58 86 0 78 88 85 12 1 52 999
I wonder if your university compiler is picky about the input file - can you remove all new lines from a copy of your input file and try running with the copied modified input file --- so it is just a stream of numbers --- see if this sorts it out...
........ in my experience of scanf and fscanf these functions can be a bit fragile if the input does not run exactly the way you say it will in the format part - here "%d" does not tell fscanf about new line characters....
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);
}