printing an X using while loops - c

I want to write a program that reads an integer n from standard input, and prints an nxn pattern of asterisks and dashes in the shape of an "X".
N has to be odd and N>= 5.
my code:
#include <stdio.h>
int main(void) {
//making sure they enter an odd number >= 5
int endloop = 0;
int size;
while (endloop == 0) {
printf("Enter size:");
scanf("%d", &size);
if (size % 2 == 0 || size < 5) {
printf("Invalid, try again\n");
} else {
endloop = 1;
}
}
int downwards = 0;
while (downwards < size) {
int across = 0;
while (across < size) {
if (downwards == across) {
printf("*");
}
if (across == size - downwards - 1) {
printf("*");
} else {
printf("-");
}
across++;
}
downwards++;
printf("\n");
}
return 0;
}
result:
Enter size:5
*----*
-*--*-
--**--
-*-*--
*---*-
it's supposed to look like this:
*---*
-*-*-
--*--
-*-*-
*---*
i can't figure out what i did wrong. The across row is printing 6 characters instead of 5 even though i stated across < size

Related

In C, can i use scanf with just one %d input but get 2 variables with that same input?

By the time i finish counting the digits(K) with a while/do loop, the original N number is lost and its now 0. So i cant rly go to step 4). Thats why i thought id create 2 variables with the same input so i can just do the 4) step as a seperate process entirely.
(CONTEXT
basically the task is to make a program that 1) read a number N (1<=N<=999999999) with scanf,
2) if the number is out of mentioned bounds, make message "Wrong Input" appear,
3) make it count the digits of said number, (digits as K),
4) If N includes K as a digit, make message "Yes" appear, otherwise make "No" appear.)
int main()
{
int K,N;
scanf("%d", &N);
if (N<=1 || N>=999999999)
{
printf("Wrong Input\n");
}
else
{
do
{
N=N/10;
K++;
}
while(N!=0);
}
return 0;
}
else
{
int M = N;
do
{
M=M/10;
K++;
}
while(M!=0);
}
You can just create a new local variable and store the value of N to be used later
#include <stdio.h>
int main() {
// initializing with 0 because 0 = false and 1 = true, to use true or false you need the bool.h header file
int containsDigit = 0;
int K, N, digits = 0;
scanf("%d", &N);
K = N;
if (N <= 1 || N >= 999999999) {
printf("Wrong Input\n");
} else {
while (N != 0) {
N /= 10;
digits++;
}
while(K != 0) {
int cdigit = K % 10;
if (cdigit == digits) {
containsDigit = 1;
break;
}
K /= 10;
}
if (containsDigit) printf("yes");
else printf("No");
}
return 0;
}

finding prime numbers between a range in C

I am trying to find the prime numbers in a range using C language. My code does not give an output and I think there is a logical error here which I cannot figure out. Can anyone please help?
#include <stdio.h>
int main() {
int lowerLevel;
int upperLevel;
int i; //counter variable
int prime = 0;
int flag = 0;
printf("Enter the lower limit and upper limit of the range followed by a comma :");
scanf("%d %d", &lowerLevel, &upperLevel);
for (i = 2; i <= upperLevel; ++i) {
if (i % 2 == 0) {
flag = 1;
break;
}
}
if (flag == 0) {
printf("%d", i);
++i;
}
return 0;
}
Your code does not check for prime numbers, it merely checks that there is at least one even number between 2 and upperlevel, which is true as soon as upperlevel >= 2. If there is such an even number, nothing is printed.
You should instead run a loop from lowerlevel to upperlevel and check if each number is a prime and if so, print it.
Here is a modified version:
#include <stdio.h>
int main() {
int lowerLevel, upperLevel;
printf("Enter the lower limit and upper limit of the range: ");
if (scanf("%d %d", &lowerLevel, &upperLevel) != 2) {
return 1;
}
for (int i = lowerLevel; i <= upperLevel; ++i) {
int isprime = 1;
for (int p = 2; p <= i / p; p += (p & 1) + 1) {
if (i % p == 0) {
isprime = 0;
break;
}
}
if (isprime) {
printf("%d ", i);
}
}
printf("\n");
return 0;
}
This method is simplistic but achieves the goal. More efficient programs would use a sieve to find all prime numbers in the range without costly divisions.
Optimal method with Sieves of Eratosthenes
You should use the sieves of Eratostenes algorithm, it is way more efficient to get the different prime number.
it does so by iteratively marking as composite (i.e., not prime) the multiples of each prime, starting with the first prime number, 2
Basically you consider all numbers prime by default, and then you will set as false the prime number, see below code:
#include <stdio.h>
/// unsigned char saves space compared to integer
#define bool unsigned char
#define true 1
#define false 0
// https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
void printPrimesRange(int lowerLevel, int n) {
if (lowerLevel < 0 || n < lowerLevel) // handle misused of function
return ;
bool isPrime[n + 1];
memset(isPrime, true, n + 1);
int cnt = 0; // NB: I use the counter only for the commas and final .\n, its optional.
if (lowerLevel <= 2 && n >= 2) { // only one even number can be prime: 2
++cnt;
printf("2");
}
for (int i = 3; i <= n ; i+=2) { // after what only odd numbers can be prime numbers
if (isPrime[i]) {
if (i >= lowerLevel) {
if (cnt++)
printf(", ");
printf("%d", i); // NB: it is better to print all at once if you can improve it
}
for (int j = i * 3; j <= n; j+=i*2) // Eratosthenes' Algo, sieve all multiples of current prime, skipping even numbers
isPrime[j] = false;
}
}
printf(".\n");
}
int main(void) {
int lowerLevel;
int upperLevel;
printf("Enter the lower limit and upper limit of the range with a space in-between:"); // space, not comma
scanf("%d %d", &lowerLevel, &upperLevel);
printPrimesRange(lowerLevel, upperLevel);
return 0;
}
Let's follow the logic of your code:
#include <stdio.h>
#include <string.h>
int main() {
int lowerLevel;
int upperLevel;
int i; //counter variable
int prime = 0;
int flag = 0;
printf("Enter the lower limit and upper limit of the range followed by a comma :");
scanf("%d %d", &lowerLevel, &upperLevel);
for (i = 2; i <= upperLevel; ++i) {
if (i % 2 == 0) {
flag = 1;
break;
}
}
if (flag == 0) {
printf("%d", i);
++i;
}
return 0;
}
First of all, you have a loop:
for (i = 2; i <= upperLevel; ++i) {
if (i % 2 == 0) {
flag = 1;
break;
}
}
this loop tries to find a number i that is a multple of 2, because as soon you get one, you jump out of the loop. So your loop can be expressed better as:
for (i = 2; i <= upperLevel && i % 2 != 0; ++i) {
}
/* i > upperLevel || i % 2 == 0 */
if (i <= upperLevel && i % 2 == 0) {
flag = 1;
}
We still need to check if i <= upperLevel && i % 2 == 0 to set the variable flag = 1 if we exited the loop because i was a multiple of 2, but the break; is not necessary because we are already out of the loop.
Now let's check that the first value we initialize i is, indeed 2 (which is a multiple of 2) and the consecuence of this is that the loop is never going to be entered. Se we can eliminate it completely, giving to:
i = 2;
if (i <= upperLevel && i % 2 == 0) {
flag = 1;
}
now, the second clause of the if test is always true, so we can take it off, giving:
i = 2;
if (i <= upperLevel) {
flag = 1;
}
Now, let's append the second part:
i = 2;
if (i <= upperLevel) {
flag = 1;
}
if (flag == 0) {
printf("%d", i);
++i;
}
return 0;
so, the first thing we see here is that your ++i; statement is nonsense, as it is the last statement to be
executed before exiting the program, so we can also take it off.
i = 2;
if (i <= upperLevel) {
flag = 1;
}
if (flag == 0) {
printf("%d", i);
}
return 0;
Now we see that you print the value of i only if the value of flag is zero, but flag only conserves its zero value if the value of i > upperLevel, and as i is fixed, the printing of i only occurs if you input a value of upperlevel that is less than 2.
We can rewrite the above code as this:
if (2 > upperLevel) {
printf("%d", 2);
}
Your program will print 2 only if you provide a value of upperLevel less than 2.

C Program (Prime Number in a given range)

I have started learning C language. I wrote this program to find all prime numbers between the given range but I am unable to get the expected output.
Can anyone tell me what's wrong with this program please?
#include <stdio.h>
#include <conio.h>
void main() {
int min, max, i, j, count = 0;
printf("Enter Your First Number\n");
scanf("%d", &min);
printf("Enter Your Last Number\n");
scanf("%d", &max);
for(i=min; i<=max; i++) {
for(j=1; j<=i; j++) {
if(i % j == 0) {
count++;
}
}
if(count==2) {
printf("%d\t",i);
}
}
getch();
}
I just suggest getting rid of that count variable.
How do you know if a number N is prime? If for every j in the range (2 to N-1) you have N%j != 0.
So:
In the inner loop, use j from 2 to N-1 (instead of from 1 to N as you used tio do). In fact N%1 and N%N will be 0
The first time you find a j so that N % j == 0 break. You are sure it's not prime
Why incrementing count? For a prime number the j counter will be equal to i (because you looped until j<i, and the last j++ made j
equal to i). So just check for j == i and print the prime number i
#include <stdio.h>
#include <conio.h>
int main( void )
{
int min, max, i, j, count = 0;
printf("Enter Your First Number\n");
scanf("%d", &min);
printf("Enter Your Last Number\n");
scanf("%d", &max);
for(i=min; i<=max; i++)
{
// Was for(j=1; j<=i; j++)
for(j=2; j<i; j++)
{
if(i % j == 0)
{
//Was count++;
break;
}
}
//Was if(count==2)
if(j == i)
{
printf("%d\t",i);
}
}
getch();
return 0;
}
Here you are.
#include <stdio.h>
int main( void )
{
printf( "Enter the range of numbers (two unsigned integer numbers): " );
unsigned int first = 0, last = 0;
scanf( "%u %u", &first, &last );
if ( last < first )
{
unsigned int tmp = first;
first = last;
last = tmp;
}
do
{
int prime = first % 2 == 0 ? first == 2 : first != 1;
for ( unsigned int i = 3; prime && i <= first / i; i += 2 )
{
prime = first % i != 0;
}
if ( prime ) printf( "%u ", first );
} while ( first++ != last );
putchar( '\n' );
return 0;
}
The program output might look like
Enter the range of numbers (two unsigned integer numbers): 0 100
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
As for your program then you need re-initialize the variable count before the inner loop
for(i=min; i<=max; i++) {
count = 0;
for(j=1; j<=i; j++) {
if(i % j == 0) {
count++;
}
}
And the inner loop is inefficient.
Need to reset the value of count. It starts at count=0, then for any inputs, the loops will count up. The For each outer loop index, it will go like this:
1 (1%1=0 --> count++, count = 1)
2 (2%1=0 --> count++, and 2%2=0 --> count++, count = 3)
3 (3%1=0 --> count++, and 3%3=0 --> count++, count = 5)
etc... until max is reached.
You can use a simple isprime function to check whether a number is prime or not and then call the function for the given interval.
To find whether a number is prime or not , we can use a simple primality test to check it.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
bool isprime(int n)
{
if(n <= 1) return false;
if(n <= 3) return true;
if(n%2 == 0 || n%3 == 0) return false;
for(int i = 5;i*i <= n;i += 6)
{
if(n%i == 0 || n%(i + 2) == 0)
{
return false;
}
}
return true;
}
int main()
{
int a,b;
printf("Enter the first number :");
scanf("%d",&a);
printf("Enter the second number :");
scanf("%d",&b);
for(int i = a;i <= b;i++)
{
if(isprime(i)) printf("%d ",i);
}
return 0;
}
There is a simple change you should do:
#include <stdio.h>
#include <conio.h>
void main() {
int min, max, i, j, count;
printf("Enter Your First Number\n");
scanf("%d", &min);
printf("Enter Your Last Number\n");
scanf("%d", &max);
for(i=min; i<=max; i++)
{
count=1;
for(j=2; j<=i; j++)
{
if(i % j == 0) {
count++;
}
}
if(count==2) {
printf("%d\t",i);
}
}
}
My answer may be a bit late, but since it's the same issue, i'll write it here in case it helps someone else coming to this thread in the future.
My code is written from the POV of a beginner (No complex functions or data types are used) as this is a code that mostly they will get stuck on.
Working:
User inputs the range.
Using the for loop, each number in the range is sent to the isprime function which returns TRUE or FALSE after checking the condition for being a prime number.
if TRUE : program prints the number.
if FALSE : program skips the number using continue function.
#include<stdio.h>
int isprime(int num);
int main() {
int min, max;
printf("Input the low number: ");
scanf("%d", &min);
printf("Input the high number: ");
scanf("%d", &max);
for(int i = min; i<=max; i++) {
if(isprime(i) == 1) {
printf("%d ", i);
}
else if(isprime(i) == 0){
continue;
}
}
return 0;
}
int isprime(int num) {
int count = 0;
for(int i=2; i<=(num/2); i++) {
if(num % i == 0 ) {
count ++;
}
else{
continue;
}
}
if(count>0){
return 0;
}
else if (count == 0){
return 1;
}
}

C program for assigning elements of a matrix without letters

I'm having trouble outputting an invalid statement if the user inputs a letter instead of a number into a 2D array.
I tried using the isalpha function to check if the input is a number or a letter, but it gives me a segmentation fault. Not sure what's wrong any tips?
the following code is just the part that assigns the elements of the matrix.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 10
void display(int matrix[][MAX], int size);
int main() {
int n, degree;
int matrix[MAX][MAX];
printf("Enter the size of the matrix: "); // assigning size of the matrix
scanf("%d", &n);
if (n <= 1 || n >= 11) { // can't be bigger than a 10x10 matrix
printf("Invalid input.");
return 0;
}
for (int i = 0; i < n; ++i) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
if (!isalpha(matrix[i][j])) { // portion I'm having trouble with
continue;
} else {
printf("Invalid input.");
return 0;
}
}
}
...
As the value of n will be number, we can solve it using string instead of int.
char num[10];
int n;
scanf("%s", num);
if(num[0] < '0' || num[0] > '9' || strlen(num) > 2){
printf("invalid\n");
}
if(strlen(num) == 1) n = num[0] - '0';
if(strlen(num) == 2 && num[0] != 1 && num[1] != 0) printf("invalid\n");
else n = 10;
Also we can use strtol() function to convert the input string to number and then check for validity.You can check the following code for it. I have skipped the string input part. Also you have to add #include<stdlib.h> at the start for the strtol() function to work.
char *check;
long val = strtol (num, &check, 10);
if ((next == num) || (*check != '\0')) {
printf ("invalid\n");
}
if(val > 10 || val < 0) printf("invalid\n");
n = (int)val; //typecasting as strtol return long
You must check the return value of scanf(): It will tell you if the input was correctly converted according to the format string. scanf() returns the number of successful conversions, which should be 1 in your case. If the user types a letter, scanf() will return 0 and the target value will be left uninitialized. Detecting this situation and either aborting or restarting input is the callers responsibility.
Here is a modified version of your code that illustrates both possibilities:
#include <stdio.h>
#define MAX 10
void display(int matrix[][MAX], int size);
int main(void) {
int n, degree;
int matrix[MAX][MAX];
printf("Enter the size of the matrix: "); // assigning size of the matrix
if (scanf("%d", &n) != 1 || n < 2 || n > 10) {
// can't be bigger than a 10x10 matrix nor smaller than 2x2
// aborting on invalid input
printf("Invalid input.");
return 1;
}
for (int i = 0; i < n; i++) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; j++) {
if (scanf("%d", &matrix[i][j]) != 1) {
// restarting on invalid input
int c;
while ((c = getchar()) != '\n') {
if (c == EOF) {
printf("unexpected end of file\n");
return 1;
}
}
printf("invalid input, try again.\n");
j--;
}
}
}
...
The isdigit() library function of stdlib in c can be used to check if the condition can be checked.
Try this:
if (isalpha (matrix[i][j])) {
printf ("Invalid input.");
return 0;
}
So if anyone in the future wants to know what I did. here is the code I used to fix the if statement. I am not expecting to put any elements greater than 10000 so if a letter or punctuation is inputted the number generated will be larger than this number. Hence the if (matrix[i][j] > 10000). May not be the fanciest way to do this, but it works and it's simple.
for (int i = 0; i < n; ++i) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
if (matrix[i][j] > 10000) { // portion "fixed"
printf("Invlaid input");
return 0;
}
}
}
I used a print statement to check the outputs of several letter and character inputs. The lowest out put is around and above 30000. So 10000 I think is a safe condition.

Weird bug which seems to be solved by adding a surplus line of code. Game of fifteen

This is a puzzle game where in a 4x4 grid one has to arrange 15 numbered tiles in order.
Most of the scenarios, the program runs fine. However, when swapping the "1" digit to the nth row, n-2th column, the program seems to bug and duplicate the number 1.
Here's the catch. When I add a random line of code, say
int blah = 0;
or
printf("abc");
The problem just magically disappears.
Because I'm unable to locate the source of the problem, I'll have to post up the entirety of it.
To see the problem, run the code without any command line arguments, then enter 2 followed by 1.
When I added the random line of code at the end of my main() function, the problem just disappears. Please try it out, and help me find out what's happening; it's really confusing.
#include <stdio.h>
#include <stdlib.h>
int n=4;
int win(int board[n][n]);
void print(int board[n][n]);
int main(int argc, char * argv[])
{
if(argc != 2)
{
printf("No valid number accepted. Board size set as 4x4.\n");
}
else if(argc == 2)
{
n = atoi(argv[1]);
if(n<2 || n>5)
{
printf("No valid number accepted. Board size set as 4x4.\n");
}
else
{
printf("Preparing board of size %dx%d\n",n,n);
}
}
int board[n][n];
printf("\n The aim of the game is to sort the board so that it runs in ascending order, from 1 to %d, from left to right and up to down starting from the top left square. To make a move, enter the number of the tile you want to move. No diagonal movement is allowed.\n\n",n*n-1);
int c = n*n-1;
for(int x = 0;x<n;x++)
{
for(int y=0;y<n;y++)
{
board[x][y] = c;
c--;
}
}
if(n%2==0)
{
int temp1 = board[n-1][n-2];
board[n-1][n-2] = board[n-1][n-3];
board[n-1][n-3] = temp1;
}
print(board);
int spacex = n-1;
int spacey = n-1;
char buffer[10];
while(win(board) == 0)
{
printf("To move, enter the number you wish to move. Take note that this number must be adjacent to the blank space. Diagonal movement is not allowed.\nYour move: ");
fgets(buffer,10,stdin);
int move;
char temp[20];
if(sscanf(buffer," %d %s",&move,temp)!= 1)
{
printf("Enter a number please.\n");
continue;
}
if(move == board[spacex+1][spacey])
{
board[spacex][spacey] = board[spacex+1][spacey];
board[spacex+1][spacey] = 0;
spacex++;
}
else if(move == board[spacex-1][spacey])
{
board[spacex][spacey] = board[spacex-1][spacey];
board[spacex-1][spacey] = 0;
spacex--;
}
else if(move == board[spacex][spacey+1])
{
board[spacex][spacey] = board[spacex][spacey+1];
board[spacex][spacey+1] = 0;
spacey++;
}
else if(move == board[spacex][spacey-1])
{
board[spacex][spacey] = board[spacex][spacey-1];
board[spacex][spacey-1] = 0;
spacey--;
}
else if(move == 0)
{
printf("Enter a valid digit please.\n");
continue;
}
else
{
printf("Enter a valid number please.\n");
continue;
}
printf("\n");
print(board);
}
printf("You won!\n");
}
///////////////////////////////////////////////////////
void print(int board[n][n])
{
for(int x=0;x<n;x++)
{
for(int y=0;y<n;y++)
{
if(board[x][y] == 0)
{
printf("__ ");
}
else
printf("%2d ",board[x][y]);
}
printf("\n\n");
}
}
///////////////////////////////////////////////////////
int win(int board[n][n])
{
int check = 1;
for(int x=0;x<n;x++)
{
for(int y=0;y<n;y++)
{
if(board[x][y] != check)
{
if(x==n-1 && y == n-1);
else
{
return 0;
}
}
check++;
}
}
return 1;
}
Any other comments about the code would be greatly appreciated too. Thanks in advance!
Code is reading out of bounds.
These two variables point to the last elements of the array board:
int spacex = n-1;
int spacey = n-1;
but are used incorrectly in all if statements. whenever a +1 is used, they will read out of bounds or read an incorrect element:
if(move == board[spacex+1][spacey])
{
board[spacex][spacey] = board[spacex+1][spacey];
board[spacex+1][spacey] = 0;
spacex++;
}
else if(move == board[spacex-1][spacey])
{
...
else if(move == board[spacex][spacey+1])
{
board[spacex][spacey] = board[spacex][spacey+1];
...

Resources