I have created a program to search for prime numbers. It works without problems until the entered number is smaller than 52, when it is bigger output prints out some blank (0) numbers and I don't know why. Also other numbers have blank output.
My code is:
#include <stdio.h> //Prime numbers
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
int c[100], n, a[50], d, e, b = 1;
void sort() {
for (int i = 1; i < n; i++) {
if (c[i] > 1) {
a[b] = c[i];
printf("%d %d %d\n", a[1], b, i);
b++;
e = 2;
d = 0;
while (d <= n) {
d = c[i] * e;
c[d - 1] = 0;
e++;
}
}
}
}
int main() {
printf("Enter number as an limit:\n");
scanf("%d", &n);
for (int i = 0; i < n; i++) {
c[i] = i + 1;
}
sort();
printf("Prime numbers between 1 and %d are:\n", n);
for (int i = 1; i < b; i++) {
printf("%d ", a[i]);
}
return 0;
}
Here is output for 25:
Enter number as an limit:
25
2 1 1
2 2 2
2 3 4
2 4 6
2 5 10
2 6 12
2 7 16
2 8 18
2 9 22
Prime numbers between 1 and 25 are:
2 3 5 7 11 13 17 19 23
But for 83 is:
Enter number as an limit:
83
2 1 1
2 2 2
2 3 4
2 4 6
2 5 10
2 6 12
2 7 16
2 8 18
2 9 22
2 10 28
2 11 30
2 12 36
2 13 40
2 14 42
2 15 46
2 16 52
0 17 58
0 18 60
0 19 66
0 20 70
0 21 72
0 22 78
0 23 82
Prime numbers between 1 and 83 are:
0 3 5 7 11 0 17 19 23 29 31 37 0 43 47 53 0 61 67 71 73 79 83
Blank spots always spots after 17th prime number. And always the blank numbers are the same. Can you help me please what is the problem?
The loop setting entries in c for multiples of c[i] runs too far: you should compute the next d before comparing against n:
for (d = c[i] * 2; d <= n; d += c[i]) {
c[d - 1] = 0;
}
As a matter of fact you could start at d = c[i] * c[i] because all lower multiples have already been seen during the previous iterations of the outer loop.
Also note that it is confusing to store i + 1 into c[i]: the code would be simpler with an array of booleans holding 1 for prime numbers and 0 for composite.
Here is a modified version:
#include <stdio.h>
int main() {
unsigned char c[101];
int a[50];
int n, b = 0;
printf("Enter number as a limit:\n");
if (scanf("%d", &n) != 1 || n < 0 || n > 100) {
printf("invalid input\n");
return 1;
}
for (int i = 0; i < n; i++) {
c[i] = 1;
}
for (int i = 2; i < n; i++) {
if (c[i] != 0) {
a[b] = i;
//printf("%d %d %d\n", a[0], b, i);
b++;
for (int d = i * i; d <= n; d += i) {
c[d] = 0;
}
}
}
printf("Prime numbers between 1 and %d are:\n", n);
for (int i = 0; i < b; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
Output:
chqrlie$ ./sieve4780
Enter number as a limit:
25
Prime numbers between 1 and 25 are:
2 3 5 7 11 13 17 19 23
chqrlie$ ./sieve4780
Enter number as a limit:
83
Prime numbers between 1 and 83 are:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79
Your problem seems to be caused by the fact that you have declared an array with size 50, but in fact it goes further than that: imagine you want to use Eratosthenes' procedure to find the first 10,000 prime numbers. Does this mean that you need to declare an array of size 10,000 first (or even bigger), risking to blow up your memory?
No: best thing to do is to work with collections where you don't need to set the maximum size at declaration time, like a linked list, a vector, ..., like that you can make your list grow as much as you like during runtime.
Related
I am trying to create a program outputting the pascal's triangle, using C in OnlineGDB and repl.it using a 2x2 array asking how many lines the user wants to print. The main problem is that the program works, but only until printing for 7 rows in onlinegdb, and only 3 rows in repl.it.
There is no error in OnlineGDB, and repl.it says "signal: segmentation fault (core dumped)"
Additionally, I added 3 "PASS" print lines to see where the error occurs, and when reaching the 8th line in onlineGDB it passes all 3 of the for statements filling the array. When reaching the 4th line in repl.it passes all 3 of the for statements filling the array, but both of them doesn't print out the correct numbers. Again, inputted numbers below these values show that all of the code works.
Is there a fix for this, or is it an error with websites handling arrays?
#include <stdio.h>
int main(void){
int intCount;
int intCount1;
int intRows;
int intColumns;
printf("HOW MANY ROWS DO YOU WANT?? ");
scanf("%i", &intRows);
intColumns = intRows;
int intNum[intRows][intColumns];
printf("PASS ");
// FIRST FILL ARRAY WITH 0
for(intCount = 0; intCount <= intRows+1; ++intCount){
for(intCount1 = 0; intCount1 <= intColumns+1; ++intCount1){
intNum[intCount][intCount1] = 0;
}
}
printf("PASS ");
// SET STARTING POINT (1)
intNum[0][0] = 1;
// NOW FILL ARRAY WITH PASCAL TRIANGLE
for(intCount = 0; intCount <= intRows; ++intCount){
for(intCount1 = 0; intCount1 <= intColumns; ++intCount1){
intNum[intCount+1][intCount1+1] = ((intNum[intCount][intCount1+1])+ (intNum[intCount][intCount1]));
}
}
printf("PASS\n");
// NOW PRINT ARRAY
for(intCount = 0; intCount <= intRows; ++intCount){
for(intCount1 = 0; intCount1 <= intColumns; ++intCount1){
// WITHOUT ZEROES:
/*if(intNum[intCount][intCount1] != 0){
printf("%5i",intNum[intCount][intCount1]);
}*/
// WITH ZEROES:
printf("%4i",intNum[intCount][intCount1]);
}
printf("\n");
}
return 0;
}
Logic: In the code above I created a 2 x 2 array with height and width dimensions one larger than the user asks for. I then fill the array with zeroes, and start with a 1 in the top left corner. From there I can use the pascals triangle formula by adding the two numbers above it
I tried changing the counting variables of arrays to make sure everything was correct, but it did not help. I originally coded on onlineGDB but used repl.it to see if there was any further errors, to which there was none. Additionally checked other questions on stack.
Desired Output:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
OnlineGDB Output: (limited to 7 rows in the input)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
repl.it Output: (limited to 3 rows in the input)
1
1 1
1 2 1
Note: In the output, my code also prints the 0s at the moment and the whole array so that I can visualize it. I am also 100% sure it's the same code uploaded to both
This could be something simple, but I appreciate all the help I can get. I'm more curious why the outputs are different on separate websites with the same code.
Why are you using loops like
for (intCount = 0; intCount <= intRows+1; ++intCount)
{
for (intCount1 = 0; intCount1 <= intColumns+1; ++intCount1)
{
intNum[intCount][intCount1] = 0;
}
}
when you allocated intNum[intRows][intColumns]? You are trampling way out of bounds. That's why your code crashes. That's why you get different behaviours in different systems.
Use:
for (int i = 0; i < intRows; i++)
{
for (int j = 0; j < int columns; j++)
intNum[i][j] = 0;
}
or an equivalent. Note that you use < and not <=; you use the declared limit, not that limit plus one.
Here is some working code, printing without the zeros. Your algorithm for generating the values in Pascal's Triangle was flawed on at least two counts. As before, it trampled way out of bounds of the array, and it also produced two rows with a single 1 in the output (when zeros were not printed). This code avoids those flaws. It also uses i and j as the loop counters — old Fortran programmers die hard.
/* SO 7549-7765 */
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int intRows;
int intColumns;
printf("How many rows do you want? ");
if (scanf("%i", &intRows) != 1)
{
fprintf(stderr, "failed to read an integer\n");
exit(1);
}
if (intRows < 1 || intRows > 64)
{
fprintf(stderr, "value %d is outside the range 1..64\n", intRows);
exit(1);
}
printf("Rows: %d\n", intRows);
intColumns = intRows;
int intNum[intRows][intColumns];
printf("PASS\n");
// First, fill array with zeros
for (int i = 0; i < intRows; i++)
{
for (int j = 0; j < intColumns; j++)
{
intNum[i][j] = 0;
}
}
printf("PASS\n");
// Set starting point (1)
intNum[0][0] = 1;
// Now fill array with Pascal's Triangle
for (int i = 1; i < intRows; i++)
{
intNum[i][0] = intNum[i-1][0];
for (int j = 1; j <= i; j++)
{
intNum[i][j] = intNum[i-1][j-1] + intNum[i-1][j];
}
}
printf("PASS\n");
// Now print array
for (int i = 0; i < intRows; i++)
{
for (int j = 0; j < intColumns; j++)
{
// Without zeros:
if (intNum[i][j] != 0)
printf(" %5d", intNum[i][j]);
// With zeros:
// printf(" %5d", intNum[i][j]);
}
printf("\n");
}
return 0;
}
Note the use of " %5d" in the printing format. That space ensures that the numbers remain separate even if there are 6 or more digits in the values (which first happens with 21 rows requested).
Sample output:
How many rows do you want? 15
Rows: 15
PASS
PASS
PASS
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1
The spacing is off in my code, can anyone help. I have attempted it (shown below)
#include <stdio.h>
int factorial(int n){
int fact = 1;
if(n == 0){
return 1;
} else {
for(int i = 1; i <= n; i++){
fact = fact * i;
}
return fact;
}
}
int choose(int n, int r)
{
int ans;
ans = (factorial(n))/((factorial(r))*(factorial(n-r)));
return ans;
}
void triangle(int numOfRows){
for(int n=0; n<numOfRows; n++)
{
for(int i=1; i<=numOfRows-n; i++){
printf(" "); // Note the extra space
}
for(int r=0; r<=n; r++)
{
printf("%5d ",choose(n,r)); // Changed to %3d
}
printf("\n");
}
}
int main(){
int rows;
printf("Enter the number of rows: ");
scanf("%d", &rows);
while(rows > 0 && rows <=13){
triangle(rows);
printf("Enter the number of rows: ");
scanf("%d", &rows);
}
return 0;
}
The expected output should be:
Thanks i'd appreciate it (this is also my first time using this site, so sorry for bad format stuff).
The program needs to work up to 13 rows (which is shown in my while loop in my main functions).
You need to make a couple of changes to have the triangle aligned to the left as in the expected output.
First, you are adding 3 extra spaces in the first loop with the printf(" "), that is fixed using < instead of <= in the loop condition.
Second, there are 4 extra chars added due to the "%5d " in the second printf call, you need to avoid that for the first iteration (when r == 0) using just "%d ".
Here's how the triangle() function will look like after the changes:
void triangle(int numOfRows) {
for(int n = 0; n < numOfRows; n++) {
for(int i = 1; i < numOfRows-n; i++) {
printf(" ");
}
for(int r = 0; r <= n; r++) {
printf(r == 0 ? "%d " : "%5d ", choose(n, r));
}
printf("\n");
}
}
And some example output (works up to 13 without a problem, at least on my 64-bit Linux with both gcc and clang):
Enter the number of rows: 3
1
1 1
1 2 1
Enter the number of rows: 4
1
1 1
1 2 1
1 3 3 1
Enter the number of rows: 5
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Enter the number of rows: 13
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
So this is my code for printing pascal triangle using 2d arrays but its not giving me the desired output and I cannot determine what's wrong with the logic/code.
#include <stdio.h>
int main()
{
int num, rows, col, k;
printf("Enter the number of rows of pascal triangle you want:");
scanf("%d", &num);
long a[100][100];
for (rows = 0; rows < num; rows++)
{
for (col = 0; col < (num - rows - 1); col++)
printf(" ");
for (k = 0; k <= rows; k++)
{
if (k == 0 || k == rows)
{
a[rows][k] = 1;
printf("%ld", a[rows][k]);
}
else
a[rows][k] = (a[rows - 1][k - 1]) + (a[rows - 1][k]);
printf("%ld", a[rows][k]);
}
printf("\n");
}
return 0;
}
You don't have curly braces around the statements after the else, so it looks like you'll double-printf() when the condition of the if-statement is true.
I copied the source into codechef.com/ide and changed the io for num to be just assigned to 6 which produced the following output:
Enter the number of rows of pascal triangle you want:
11
1111
11211
113311
1146411
1151010511
It looks like your close, but you want 1, 11, 121, 1331 etc right?
Wraping the else case produced the following output:
if (k == 0 || k == rows)
{
a[rows][k] = 1;
printf("(%ld)", a[rows][k]);
}
else{// START OF BLOCK HERE
a[rows][k] = (a[rows - 1][k - 1]) + (a[rows - 1][k]);
printf("(%ld)", a[rows][k]);
}//END OF BLOCK HERE, NOTE THAT IT INCLUDES THE PRINT IN THE ELSE CASE NOW
OUTPUT:
Enter the number of rows of pascal triangle you want:
(1)
(1)(1)
(1)(2)(1)
(1)(3)(3)(1)
(1)(4)(6)(4)(1)
(1)(5)(10)(10)(5)(1)
But i added () to make it clearer to me. I also added a "/n" to the end of the first printf that asks for the value of num, so that the first line is on a new line.
printf("Enter the number of rows of pascal triangle you want:\n");
You can do that without using any arrays:
#include <stdlib.h>
#include <stdio.h>
int num_digits(int number)
{
int digits = 0;
while (number) {
number /= 10;
++digits;
}
return digits;
}
unsigned max_pascal_value(int row)
{
int result = 1;
for (int num = row, denom = 1; num > denom; --num, ++denom)
result = (int)(result * (double)num / denom );
return result;
}
int main()
{
printf("Enter the number of rows of pascals triangle you want: ");
int rows;
if (scanf("%d", &rows) != 1) {
fputs("Input error. Expected an integer :(\n\n", stderr);
return EXIT_FAILURE;
}
int max_digits = num_digits(max_pascal_value(rows));
for (int i = 0; i <= rows; ++i) {
for (int k = 0; k < (rows - i) * max_digits / 2; ++k)
putchar(' ');
int previous = 1;
printf("%*i ", max_digits, previous);
for (int num = i, denom = 1; num; --num, ++denom) {
previous = (int)(previous * (double)num / denom );
printf("%*i ", max_digits, previous);
}
putchar('\n');
}
}
Output:
Enter the number of rows of pascals triangle you want: 15
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1
1 15 105 455 1365 3003 5005 6435 6435 5005 3003 1365 455 105 15 1
int main (void)
{
int range, i, j;
printf("Input size of multiplication table: ");
scanf("%i", &range);
int output[range][range];
for (i = 0; i<=range; ++i)
{
for (j=0; j<=range; ++j)
{
output[i][j] = i * j;
if(j!=range && output[i][j] != 0)
{
printf("%3i ", output[i][j]);
}
else if (j==range)
{
printf("%3i", output[i][j]);
}
else if (output[i][j] == 0)
{
printf("%3i "), i+2;
}
else
{
printf("%3i", j + i - range);
}
}
printf("\n");
}
return 0;
}
I am having it output:
0 1 2 3 4 0
5 1 2 3 4 5
10 2 4 6 8 10
15 3 6 9 12 15
20 4 8 12 16 20
25 5 10 15 20 25
and I need the 0 on the end to be a five and the first column to be 0,1,2,3,4,5 instead of 0,5,10,15,20,25.
If anyone could help I would appreciate it.
You have two primary problems, (1) you fail to validate your user input, and (2) your loop bounds are incorrect, e.g.
Any time you take user input, you must validate that you actually received what you expected and that any conversion required, was completed successfully. Failure to validate will lead to Undefined Behavior it invalid (or no) input is provide. (e.g. What if the user enters foo instead of 10?) When using scanf, you must validate the return which provides the count of the number of conversions that successfully took place, e.g.
printf ("Input size of multiplication table: ");
if (scanf("%i", &range) != 1) { /* VALIDATE ALL USER INPUT */
fprintf (stderr, "error: invalid input.\n");
return 1;
}
That is bare minimum. You can also check if the return is EOF to indicate the user canceled input with a [Ctrl+D] (or [Ctrl+Z] on windoze -- must be explicitly enabled on Win10).
Next, your loop bound are for (i = 0; i < range; i++) not i <= range, that invokes Undefined Behavior by attempting to access memory outside your array bounds. Simply fix the loop condition, e.g.
for (i = 0; i< range; i++) { /* fill multiplication table */
for (j = 0; j< range; j++) {
output[i][j] = (i + 1) * (j + 1); /* i+1 * j+1 */
}
}
Putting it altogether, you could do something similar to:
#include <stdio.h>
int main (void) {
int range, i, j;
printf ("Input size of multiplication table: ");
if (scanf("%i", &range) != 1) { /* VALIDATE ALL USER INPUT */
fprintf (stderr, "error: invalid input.\n");
return 1;
}
int output[range][range]; /* variable length array */
for (i = 0; i< range; i++) { /* fill multiplication table */
for (j = 0; j< range; j++) {
output[i][j] = (i + 1) * (j + 1); /* i+1 * j+1 */
}
}
for (i = 0; i< range; i++) { /* output table */
for (j = 0; j< range; j++)
printf (" %3d", output[i][j]);
putchar ('\n');
}
return 0;
}
note: the trivial parts of the table is omitted (e.g. 0 * anything), and duplicated rows of 1 * anything are also not shown. If you need to additional rows, you can add them back.
Example Use/Output
$ ./bin/multable
Input size of multiplication table: 10
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
Look things over and let me know if you have further questions.
To Show the 1X Rows
You simply update your print routine as follows:
for (i = 0; i< range; i++) { /* output table */
if (!i) {
printf (" ");
for (j = 0; j< range; j++)
printf (" %3d", output[i][j]);
putchar ('\n');
}
printf (" %3d", i + 1);
for (j = 0; j< range; j++)
printf (" %3d", output[i][j]);
putchar ('\n');
}
Example Use/Output
$ ./bin/multable1
Input size of multiplication table: 10
1 2 3 4 5 6 7 8 9 10
1 1 2 3 4 5 6 7 8 9 10
2 2 4 6 8 10 12 14 16 18 20
3 3 6 9 12 15 18 21 24 27 30
4 4 8 12 16 20 24 28 32 36 40
5 5 10 15 20 25 30 35 40 45 50
6 6 12 18 24 30 36 42 48 54 60
7 7 14 21 28 35 42 49 56 63 70
8 8 16 24 32 40 48 56 64 72 80
9 9 18 27 36 45 54 63 72 81 90
10 10 20 30 40 50 60 70 80 90 100
Check the solution below. It's all about properly managing iterators (note the less-equal sign in the ranges and the subtraction of indexes by 1 in the assignment). You can do it very concisely by assigning to output inside the printf and using a ternary-if. (I also used dynamic allocation in order to comply with ISO standards.)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int range, i, j;
printf("Enter the size of the multiplication table:\n");
scanf("%d", &range);
int ** output = (int **) malloc(sizeof(int *) * (long unsigned int) range);
for(i = 0; i <= range; ++i)
{
output[i] = (int *) malloc(sizeof(int) * (long unsigned int) range);
for(j = 0; j <= range; ++j)
printf("%3d ", !i ? j : !j ? i : (output[i - 1][j - 1] = i * j));
printf("\n");
}
return 0;
}
Recently, I encountered with a problem that asked me to write a dynamic code that print n x n matrix in a zigzag pattern. Please help me with the code to get the output stated below.
Output:
rows: 5
cols: 5
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
21 22 23 24 25
The Code that I've tried so far is in static:
#include <stdio.h>
int main(){
int arr[3][3]={1,2,3,
4,5,6,
7,8,9};
int i, j, k;
for(i=0; i<3; i++){
printf("%d",arr[0][i]);
}
printf("\n");
for(j=2; j>=0; j--){
printf("%d",arr[1][j]);
}
printf("\n");
for(k=0; k<3; k++){
printf("%d",arr[2][k]);
}
printf("\n");
return 0;
}
Now I want the same thing to be done with the user stating rows and columns of an array..
This should work for you:
#include <stdio.h>
int main() {
int rows, columns;
int rowCount, columnCount, count = 0;
printf("Please enter rows and columns:\n>");
scanf("%d %d", &rows, &columns);
for(rowCount = 0; rowCount < rows; rowCount++) {
for(columnCount = 1; columnCount <= columns; columnCount++) {
if(count % 2 == 0)
printf("%4d " , (columnCount+(rowCount*columns)));
else
printf("%4d " , ((rowCount+1)*columns)-columnCount+1);
}
count++;
printf("\n");
}
return 0;
}
Input:
5 5
Output:
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
21 22 23 24 25
Simple dynamic logic with k variable
#include <stdio.h>
int main() {
int i,j,k=1,row,col;
printf("Enter row and col \n>");
scanf("%d %d", &row, &col);
for (i = 1; i <=row; i++)
{
for (j = 1; j <=col; j++)
{
if(i%2==0) k--;
printf("%4d",k); // it have to be in center of both condition
if(i%2!=0) k++;
}
k=k+col;
printf("\n");
}
return 0;
}
Input :
7 7
Output :
1 2 3 4 5 6 7
14 13 12 11 10 9 8
15 16 17 18 19 20 21
28 27 26 25 24 23 22
29 30 31 32 33 34 35
42 41 40 39 38 37 36
43 44 45 46 47 48 49