Error in scanf() - c

first of all, I've got a logical error in my code. Well, this is the code
#include <stdio.h>
int main()
{
long i,j,t;
scanf("%ld",&t);
long n[t],d[t][t];
for(i = 0; i < t;i++){
scanf("%ld",&n[i]);
for(j = 0; j < n[i] ;j++){
scanf("%ld",&d[j][i]);
}
}
for(i = 0; i < t;i++){
for(j = 0; j < n[i] ;j++){
printf("%ld ",d[j][i]);
}
printf("\n");
}
return 0;
}
And I input the data
2
4
25 20 30 90
3
45 50 55
And the result is
25 20 30 90
45 50 55
Well, that's what I expected. However, when the input become like this
3
5
12 67 89 34 56
6
34 56 78 90 12 34
7
12 34 89 23 56 78 89
The result become like this
12 34 89 23 56 78 89
12 67 89 34 56 4206692 7 2293472 1982002386 16 3 2293344 2293408 0 2293552 0 0 4
198585 8918456 1982106837 1982010910 8918456 2293640 0 0 1985286516 2009576437 0
0 2293664 2009323341 2293740 2147348480 0
34 56 78 90 12 34 4199405 1982595752 8 12 2293424 2 2 1982356412 2147348480 2293
608 2147348480 1 -1 297753669 1982010784 1982015505 4199044 0 0 2147348480 21473
48480 0 0 0 7273647 2009576392 0 0 0 1 0 20 52 0 0 438759246 736 -214797894 1420
760826203 2272 852421325 3108 944791496 4028 -1322777276 4988 9 1 1 1204 7168 4
2 152 11832 7 1 40 12316 1682469715 1 140 44 0 0 0 2 0 7209065 5701724 6029427
12 34 89 23 56 78 89
Well, the simple question, why the output become like the above?? When I input above 2, the same result will be happened. Any possible answers and links if you don't mind it?? Thanks

You are writing outside your 2D array in many cases, sometimes you don't get errors, but that's just by chance.
You determine the size of the 2D array by the number of arrays to be inputted, but you also determine the size of the inner arrays at the same time:
scanf("%ld",&t);
long n[t],d[t][t];
So for example, let's take the first example:
2 >> create array n[2], and array d[2][2]
4 >> number of values to d[0]
25 20 30 90 >> d[0][1] = 25 d[0][2] = 20 you access d[0][3] and d[0][4] but you are not allowed to do that.
3 >> number of values to d[1]
45 50 55 >> d[1][0] = 45 d[1][1] = 50 you access d[1][2] but you are not allowed to do that

You build a matrix with size t*t, then fill in rows with more or less elements.
If you fill a row with too few elements, the rest remain uninitialized, and you get strange numbers. It's OK in your case, because you don't print these elements.
If you fill a row with too many elements, the excess overlaps into the next row. It may also exceed the whole matrix and corrupt your stack.
I guess this is what's going on - your n array is overrun, and your code goes crazy.

I believe that you can use malloc.
#include <stdio.h>
#include <stdlib.h>
int main()
{
long i,j,t;
printf("Rows : ");
scanf("%ld",&t);
long *n;
long **d;
n = (long* )malloc(sizeof(long) * t); // add malloc
d = (long** )malloc(sizeof(long *) * t); // add malloc
for(i = 0; i < t;i++){
printf("Column : ");
scanf("%ld",&n[i]);
d[i] = (long* )malloc(sizeof(long) * n[i]); //add malloc
if(d[i] == NULL)
printf("ERROR\n");
for(j = 0; j < n[i] ;j++){
scanf("%ld", &d[i][j]); // change from &d[j][i]
}
}
printf("\n\n");
for(i = 0; i < t;i++){
for(j = 0; j < n[i] ;j++){
printf("%ld ",d[i][j]); // change from d[j][i]
}
printf("\n");
}
return 0;
}
Well, the simple question, why the output become like the above?? When
I input above 2, the same result will be happened. Any possible
answers and links if you don't mind it?? Thanks
because you allocate less memory than used.
scanf("%ld", &d[j][i]); you have to exchange the "i" and "j".

Related

Why is there a segmentation-fault error only with certain input values on pascal's triangle? (C)

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

Eratosthenes prime numbers

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.

Array is printing with weird question mark symbols when printing fibonacci sequences

When printing each Fibonacci sequence the first couple of sequences print in weird symbols or not at all if printing more than 8 sequences.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
//n=amount of numbers in the series to compute, seq=array to store series
void fibonacci(int n, int* seq){
// Complete this function
int i;
seq[0] = 0;
seq[1] = 1;
for(i = 2; i <= n; i++){
seq[i] = seq[i-2] + seq[i-1];
}
}
int main(){
int n;
//n, amount of series to compute
scanf("%d",&n);
//initialize array to 1, using malloc/calloc
int *seq = malloc(1 * sizeof(*seq));
int i;
for(i = 1; i <= n; i++){
//recompute the whole series
fibonacci(i, seq);
//print array
int j;
for(j = 0; j < i; j++)/* complete code */
printf("%d ", seq[j]);
//resize array, with realloc
int newSize=i+1;
int *seq = realloc(seq, newSize);
printf("\n");
}
//free array
return 0;
}
Output:
"7Y��yb�=
Um�*/E�o 1 1 2 3 5 8 13
0 1 1 2 3 5 8 13 21
0 1 1 2 3 5 8 13 21 34
0 1 1 2 3 5 8 13 21 34 55
0 1 1 2 3 5 8 13 21 34 55 89
0 1 1 2 3 5 8 13 21 34 55 89 144
0 1 1 2 3 5 8 13 21 34 55 89 144 233
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946
There are different problems in your code:
In your fibonacci() function, you iterate using i <= n, but inside the loop, you assign to seq[i]. When i = n, this becomes a problem: you're accessing one cell out of the array.
You are getting n from user input, but then doing int *seq = malloc(1 * sizeof(*seq)). You are only allocating space for one element, not n. You should do malloc(n * sizeof(*seq)) instead.
Not really an error, but inside the first for loop in your main, you're both re-defining and re-allocating the seq array with int *seq = realloc(...). That is not needed at all. Your array is already n cells big, so there is no need to reallocate it each time. You can use it as is.
Not really an error, but there is no need to recompute the series each time. You can compute it only once and then partially print it on each row without a problem.
Also, IMPORTANT! Using int to hold numbers of the Fibonacci sequence is only good until you reach n = 47. More than that, and your next element will overflow the maximum positive value that an int can hold, turning negative, and invalidating the rest of the calculations too. I would suggest you to use long long unsigned int instead, which would be good up to n = 94 (assuming 64 bits). Ultimately, you should check the value of n before calculating the Fibonacci sequence to avoid an overflow.
Here's a better version of your code with those problems fixed:
void fibonacci(int n, int* seq) {
int i;
seq[0] = 0;
seq[1] = 1;
for(i = 2; i < n; i++)
seq[i] = seq[i-2] + seq[i-1];
}
int main() {
int *seq;
int n, i, j;
scanf("%d",&n);
// Allocate enough space for n elements:
seq = malloc(n * sizeof(*seq));
// Compute the whole series once:
fibonacci(n, seq);
// Print partial series on each row:
for(i = 1; i <= n; i++) {
for(j = 0; j < i; j++)
printf("%d ", seq[j]);
printf("\n");
}
free(seq);
return 0;
}

Trying to get a user input to make a 2-D array multiplication table

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;
}

SIGXFSZ runtime error

I'm trying to submit the solution for Spoj - Prime Intervals problem. But I'm getting a runtime error SIGXFSZ. It is given that, it occurs due to exceeded file size. I have used the Sieve of Eratosthenes algorithm to find the prime numbers. I don't understand what's wrong with my code and this is bugging me from last the 2 days. Please help me with the submission. Here is my code...
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
int main(){
int t, turn;
long i, l,u,k,j;
scanf("%d", &t);
/*Looping for t test cases*/
for(turn=0; turn<t; turn++){
scanf("%ld %ld", &l, &u);
bool arr[u-l+1];
/*Assigning whole array with true*/
memset(arr, true, u-l+1);
/*Sieve of Eratosthenes logic for assigning false to composite values*/
for(i=0; i<=(int)sqrt(u)-l; i++){
k=0;
j = i+l;
if(arr[i]==true){
while((j*j + k*j) <= u){
arr[(j*j + k*j) - l] = false;
k++;
}
}
}
/*Printing all the primes in the interval*/
for(i=0; i<u-l; i++){
if(arr[i]==true){
printf("%ld\n", i+l);
}
}
}
return 0;
}
Test Input:
2
2 10
2 100
Output:
2
3
5
7
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
I ran the posted code. the results were far from correct.
Most of the numbers output are not primes and fails to check the last number is the range, as shown in the second set of results
Here are the results:
1 <-- 1 test case
20 100 <-- range 20...100
20 <-- the outputs
21
22
23
24
25
26
27
28
29
30
31
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
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
Note: using 1 as the low end of the range usually results with no output produced
here is another run
The output should have been 5 7 11
1 <-- test cases
5 11 <-- range
5 <-- outputs
6
7
8
9
10
The following code does not try to minimize the size of the arr[] array, and if the upper end of the range is less than 16k then could declare the arr[] as short rather than unsigned int
The lowest valid value for the low end of the input is 2, but the code is not checking for that low limit, you might want to add that check.
The code makes no effort to minimize the number of loops executed by checking for the square root of the upper limit, you might want to add that check.
The code compiles cleanly, handles the case when the upper limit is a prime and when the lower limit is a prime as well as when the limit values are not primes.
#include <stdio.h>
#include <string.h>
#include <math.h>
int main()
{
int numTestCases, testCase;
size_t i; // index
size_t lowLimit;
size_t upperLimit;
size_t k; // offset multiplier
scanf("%d", &numTestCases);
/*Looping for t test cases*/
for(testCase=0; testCase<numTestCases; testCase++)
{
scanf("%lu %lu", (unsigned long*)&lowLimit, (unsigned long*)&upperLimit);
unsigned arr[upperLimit+1];
/*Assigning whole array to indicate entry is a prime*/
memset(arr, 0x01, upperLimit+1);
/*Sieve of Eratosthenes logic for assigning false to composite values*/
//size_t sqrtUpperLimit = (size_t)ceil(sqrt(upperLimit));
for(i=2; i<= upperLimit; i++)
{
if(arr[i])
{
if( i >= lowLimit )
{
printf("%ld\n", i);
}
for( k=2; (i*k) <= upperLimit; k++)
{
arr[(i*k)] = 0;
}
}
}
}
return 0;
} // end function; main
here is an edited version of the code, with the addition of some instrumentation in the way of prompts to the user via calls to printf()
#include <stdio.h>
#include <string.h>
#include <math.h>
int main()
{
int numTestCases, testCase;
size_t i; // index
size_t lowLimit;
size_t upperLimit;
size_t k; // offset multiplier
printf("enter number of test cases\n");
scanf("%d", &numTestCases);
/*Looping for t test cases*/
for(testCase=0; testCase<numTestCases; testCase++)
{
printf( "enter lower limit upper limit limits\n");
scanf("%lu %lu", (unsigned long*)&lowLimit, (unsigned long*)&upperLimit);
unsigned arr[upperLimit+1];
/*Assigning whole array to indicate entry is a prime*/
memset(arr, 0x01, upperLimit+1);
/*Sieve of Eratosthenes logic for assigning false to composite values*/
//size_t sqrtUpperLimit = (size_t)ceil(sqrt(upperLimit));
for(i=2; i<= upperLimit; i++)
{
if(arr[i])
{
if( i >= lowLimit )
{
printf("%ld\n", i);
}
for( k=2; (i*k) <= upperLimit; k++)
{
arr[(i*k)] = 0;
}
}
}
}
return 0;
} // end function; main
Using the above instrumented code and the input of:
5 2 3 30 31 20 27 2 3 4 5
it worked perfectly.
This was the output:
enter number of test cases
5
enter upper/lower limits
2 3
sizeof arr[]: 4
2
3
enter upper/lower limits
30 31
sizeof arr[]: 32
31
enter upper/lower limits
20 27
sizeof arr[]: 28
23
enter upper/lower limits
2 3
sizeof arr[]: 4
2
3
enter upper/lower limits
4 5
sizeof arr[]: 6
5

Resources