Simple I/O Function w/ C - c

I've just recently started trying to learn C through the tutorials on Wikibooks. I've read the beginning C pages listed here and am attempting to do the exercises. I'm having a problem with the second question on loops: wherein I'm trying to make a function to output a triangle made up of lines of * characters, where the height is 2n-1 if the width is n. My first thought was to make a nested loop, the outer of which would create a variable for the line number, and compare it to the max height. The inner loop would create a variable that would essentially serve as the index of the * character within that particular line. My problem is I don't know how to deal with making the lines after the max width decrease in size. Can anyone point me in the right direction? Here is my code:
#include <stdio.h>
void triangle(int);
int main() {
int width;
printf("%s", "Please enter a width for your triangle: ");
scanf("%d", & width);
triangle(width);
return 0;
}
void triangle(int width) {
for (int line = 1; line <= (2 * width) - 1; line++) {
for (int i = 0; i < line && i < width; i++) {
printf("%s", "*");
}
printf("%s", "\n");
}
}

Try this:
void triangle(int width) {
int line, i, rev = 0;
for (line = 1; line < width; ++line) {
for (i = 0; i < line && i < width; i++) {
printf("*");
}
printf("\n");
}
for (; line; --line) {
for (i = 0; i < line && i < width; i++) {
printf("*");
}
printf("\n");
}
}

if you want to do it in one pair of nested for loops try this:
void triangle(int width) {
int i, j, height, tmp;
height = 2 * width - 1;
tmp = 1;
for (i = 0; i < height; i++) {
for (j = 0; j < tmp; j++) {
putchar('*');
}
putchar('\n');
if (i < height / 2) {
tmp++;
} else {
tmp--;
}
}
}

Related

Print elements of an array that appear only once (C)

I am having trouble achieving the wanted results. The program should ask for 20 inputs and then go over each to see if they appear more than once. Then only print out those that appeared once.
However currently my program prints out random numbers that are not inputted.
For example:
array = {10,10,11,12,10,10,10.....,10} should return 11 and 12
#include <stdio.h>
void main() {
int count, size=20, array[size], newArr[size];
int number=0;
for(count = 0; count < size; count++) {
// Ask user for input until 20 correct inputs.
printf("\nAnna %d. luku > ", count+1);
scanf("%d", &number);
if( (number > 100) || (number < 10) ) {
while(1) {
number = 0;
printf("Ei kelpaa.\n");//"Is not valid"
printf("Yrita uudelleen > ");//"Try again >"
scanf("%d", &number);
if ( (number <= 100) && (number >= 10) ) {
break;
}
}
}
array[count] = number;
}
for(int i=0; i < size; i++) {
for(int j=0; j<size; j++){
if(array[i] == array[j]){
size--;
break;
} else {
// if not duplicate add to the new array
newArr[i] == array[j];
}
}
}
// print out all the elements of the new array
for(int k=0; k<size; k++) {
printf("%d\n", newArr[k]);
}
}
You don't need the newArr here, or the separate output loop. Only keep a count that you reset to zero at the beginning of the outer loop, and increase in the inner loop if you find a duplicate.
Once the inner loop is finished, and the counter is 1 then you don't have any duplicates and you print the value.
In code perhaps something like:
for (unsigned i = 0; i < size; ++i)
{
unsigned counter = 0;
for (unsigned j = 0; j < size; ++j)
{
if (array[i] == array[j])
{
++counter;
}
}
if (counter == 1)
{
printf("%d\n", array[i]);
}
}
Note that the above is a pretty naive and brute-force way to deal with it, and that it will not perform very well for larger array sizes.
Then one could implement a hash-table, where the value is the key, and the count is the data.
Each time you read a value you increase the data for that value.
Once done iterate over the map and print all values whose data (counter) is 1.
Use functions!!
Use proper types for indexes (size_t).
void printdistinct(const int *arr, size_t size)
{
int dist;
for(size_t s = 0; s < size; s++)
{
int val = arr[s];
dist = 1;
for(size_t n = 0; n < size; n++)
{
if(s != n)
if(val == arr[n]) {dist = 0; break;}
}
if(dist) printf("%d ", val);
}
printf("\n");
}
int main(void)
{
int test[] = {10,10,11,12,10,10,10,10};
printdistinct(test, sizeof(test)/sizeof(test[0]));
fflush(stdout);
}
https://godbolt.org/z/5bKfdn9Wv
This is how I did it and it should work for your:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <stdarg.h>
void printdistinct(const int *muis, size_t size);
int main()
{
int loop=20,i,muis[20],monesko=0;
for(i=0; i<loop; i++){
monesko++;
printf ("Anna %d. luku: \n",monesko);
scanf("%d", &muis[i]);
if (muis[i]<10 || muis[i]>100){
printf("Ei kelpaa!\n");
muis[i] = muis[i + 1];
printf("YRITÄ UUDELLEEN:\n ");
scanf("%d", &muis[i]);
}
}
printdistinct(muis, sizeof(muis)/sizeof(muis[0]));
fflush(stdout);
return 0;
}
void printdistinct(const int *muis, size_t size)
{
for(size_t s = 0; s < size; s++)
{
int a = muis[s];
int testi = 1;
for(size_t n = 0; n < size; n++){
if(s != n) {
if(a == muis[n]){
testi = 0;
break;
}
}
}
if(testi) {
printf("%d \n", a);
}
testi = 1;
}
printf("\n");
}
This approach uses some memory to keep track of which elements are duplicates. The memory cost is higher, but the processor time cost is lower. These differences will become significant at higher values of size.
char* duplicate = calloc(size, 1); // values are initialized to zero
for (unsigned i = 0; i < size; ++i)
{
if(!duplicate[i]) // skip any value that's known to be a duplicate
{
for (unsigned j = i + 1; j < size; ++j) // only look at following values
{
if (array[i] == array[j])
{
duplicate[i] = 1;
duplicate[j] = 1; // all duplicates will be marked
}
}
if (!duplicate[i])
{
printf("%d\n", array[i]);
}
}
}
What you can do is you can initialize a hashmap that will help you store the unique elements. Once you start iterating the array you check for that element in the hashmap. If it is not present in the hashmap add it to the hashmap. If it is already present keep iterating.
This way you would not have to iterate the loop twice. Your time complexity of the algorithm will be O(n).
unordered_map < int, int > map;
for (int i = 0; i < size; i++) {
// Check if present in the hashmap
if (map.find(arr[i]) == map.end()) {
// Insert the element in the hash map
map[arr[i]] = arr[i];
cout << arr[i] << " ";
}
}

CS50 coding exercise Mario less comfortable

I am new to any programming and new to computer science in general. This exercise was a real headache for me and I spent maybe two days reading stuff and trying to find how to write a solution for it.
I used a lot of information I found everywhere to make my "own" code. It's not mine really.
Now with all this job that I've done I still don't get why do I get one extra space printed at the beginning of every row. When there is let's say 5 rows and the height is 5 there is one extra space at the beginning. Could anyone explain to me what am I doing wrong, please? Thank you
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int height;
do
{
height = get_int("Height: ");
}
while (height < 1 || height > 9);
for (int row = 1; row <= height; row++)
{
{
printf(" ");
}
for (int k = 1; k <= height - row; k++)
{
printf(" ");
}
for (int j = 1; j <= row; j++)
{
printf("#");
}
printf("\n");
}
return 0;
}
Let's trace you for loop
for (int row = 1; row <= height; row++)
{
// print space at first of row
{
printf(" ");
}
// print space as how many rows left
for (int k = 1; k <= height - row; k++)
{
printf(" ");
}
// print # for each row
for (int j = 1; j <= row; j++)
{
printf("#");
}
// new line
printf("\n");
}
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int height=10;
for (int i= 1; i <= height; i++)
{
for(int j=height-1;j>=i;j--)
{
printf(" ");//print a space : ' '
}
for(int k=1;k<=i;k++)
{
printf("#");//print this caracter :'#'
}
printf("\n");
}
return 0;
}
You have 3 for loops.
Inside the outermost loop, there are two for loops. Your code first prints a space, and then runs the two inner for loops.
The second for loop also prints a space.
The third for loop prints a number of # characters depending on the height of the tower.
If you're asking why there's an extra space, it's that first statement in the for loop.
I'm no C expert but i believe the braces are unnecessary. Remove that and your code should not have extra spaces.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int height;
do
{
height = get_int("Height: ");
}
while (height < 1 || height > 9);
for (int row = 1; row <= height; row++)
{
for (int k = 1; k <= height - row; k++)
{
printf(" ");
}
for (int j = 1; j <= row; j++)
{
printf("#");
}
printf("\n");
}
return 0;
}

How to print a 2D array with dots inside them in C

how would I input a 2D array in C, filled with dots?
Here is the code I have written so far, but I still don't see an output of a 2D array with dots.
#include <stdio.h>
#include <stdlib.h>
#define PLAYER_NONE 0
#define PLAYER 1
#define PLAYER_CPU 2
int i; // Global Variable for column and row
int j; // Global Variable for column and row
char playerBoard[8][8]; //Global Variable
char cpuBoard[8][8]; // Global Variable
//Initialise the main parts of the board
void initialise_board(void)
{
for (int i = 0; i < 8; i++) { //iterate the rows
for (int j = 0; j < 8; j++) {
cpuBoard[i][j] = '.';
}
}
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
playerBoard[i][j] = '.';
}
}
}
int main(int argc, char *argv[])
{
initialise_board();
while (!check_win()) {
display_board();
get_move(turn);
turn = (turn == 1) ? 2 : 1;
return 0;
}
//Display battleship board when a turn is played
void display_board()
{
printf("\n");
for (char i = 'A'; i < 'H' + 1; i++) {
printf("%c", i);
}
printf("\n");
for (i = 1; i < 8 + 1; i++) {
printf("%d",i);
for (j = 0; j < 8; j++) {
}
printf("\n");
}
printf("===");
printf("\n");
}
Any help would be much appreciated, Thank you very much
Sometimes, while troubleshooting a seemingly impossible problem, it is a good idea to remove all distractions from the code:
Run a simplified main() function:
int main(int argc, char *argv[])
{
initialise_board();
//while (!check_win()) {
display_board();
// get_move(turn);
// turn = (turn == 1) ? 2 : 1;
return 0;
}
And you will see some output, which you can then debug to adjust as needed.
However, As you point out in your comments, you are not seeing output. If you look closely, you will discover that is because you are never including cpuBoard or playerBoard in a printf statement, such as:
printf("%c", cpuBoard[i][j]);
The following will not finish this for you, but will get you started:
void display_board(void)
{
//printf("\n");//removed for illustration
//for (char i = 'A'; i < 'H' + 1; i++) {
// printf("%c", i);
//}
printf("\n");
for (i = 1; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
printf("%c", cpuBoard[i][j]); //illustrates printout of populated array cpuboard.
}
printf("\n");
}
printf("===");
printf("\n");
}
Your code looks fine. Check for the opening and closing brackets and add following statement in initializeboard() function :
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
printf("%c",playerBoard[i][j]);
}
}

update ascii grid printed to the screen without reprinting grid

int main() {
struct matrix m;
m.rows = 20;
m.columns = 20;
m.grid = create_grid(m.rows,m.columns,'&');
/* Example animation */
printf("\033[H\033[2J");
for (int i = 0; i < m.columns; i++) {
update_matrix(m.grid,10,i,'x');
if ( i > 0) {
update_matrix(m.grid,10,i-1,'&');
}
printf("\033[H\033[2J");
sleep(1);
printMatrix(m.grid,m.rows,m.columns);
}
for (int i = 0; i < m.rows; i++) {
free(m.grid[i]);
}
free(m.grid);
return 0;
}
void update_matrix(char** grid, int row,int column,char symbol) {
grid[row][column] = symbol;
}
char** create_grid(int rows, int columns, char symbol) {
int i,j;
char **grid = malloc(rows * sizeof(char *));
for (i = 0; i < rows; i++) {
grid[i] = malloc(columns * sizeof(char));
}
for (i = 0; i < rows; i++) {
for(j = 0; j < columns; j++) {
grid[i][j] = symbol;
}
}
return grid;
}
void printMatrix(char** array, int rows, int columns) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
printf("%c",array[i][j]);
}
printf("\n");
}
}
my method of animation is essentially to...
print the matrix
update the matrix
pause
clear the screen
reprint the matrix
The problem with this method of animation is that it creates a flickering effect and i'm sure is very inefficient. What can I do so that I do not have to clear the screen and reprint the entire matrix each time.
I run linux.
Apart from using ncurses, you could do
printf("\033%d;%df", row, column);
to set the cursor to the required row and column (note that in here, first row is 1 and not 0) instead of
printf("\033[H\033[2J");
Print the matrix once after setting it up and then change the displayed matrix when modifications are made.
You might want to position the cursor to the first row and column before printing the initial matrix like
printf("\033[%d;%df", 1, 1);
m.grid = create_grid(m.rows,m.columns,'&');
printMatrix(m.grid, m.rows, m.columns);
/* Example animation */
for (int i = 0; i < m.columns; i++) {
update_matrix(m.grid,10,i,'x');
printf("%c[%d;%df", 0x1B, 10+1, i+1);
printf("%c", 'x');
if ( i > 0) {
update_matrix(m.grid,10,i-1,'&');
printf("%c[%d;%df", 0x1B, 10+1, i-1+1);
printf("%c", '&');
}
sleep(1);
fflush(stdout);
}
fflush(stdout); may be needed to flush the output stream. Otherwise the changes written to stdout may not come on screen the moment they are changed.
But for such uses ncurses is better.
Have a look here and at this wikipedia page as well.

Square Issue in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Okay so I swear this code should work, but obviously it doesn't. I am attempting to create a Snake game in C, however my Stage isn't displaying correctly. I am attempting to make it so the stage has no characters displaying inside, but only around the perimeter, can anyone assist me?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* boolean functions */
#define TRUE 1;
#define FALSE 0;
/* board */
const int length = 20;
const int height = 20;
/* Global Variables */
int x, y, foodX, foodY;
int gameEnd;
int score;
/* movement */
typedef enum {STOP = 0, UP, DOWN, LEFT, RIGHT} movement;
movement move;
/* Game Setup */
void Game()
{
gameEnd = FALSE;
move = STOP;
y = height / 2;
x = length / 2;
foodX = rand() % length;
foodY = rand() % height;
score = 0;
}
/* What is displayed on screen */
void Display()
{
system("cls");
int i;
for( i = 0; i < length + 2; i++)
printf("#\n");
for( i = 0; i < height; i++)
{
int j;
for(j = 0; j < length; j++)
{
if( j == 0 )
printf("#");
printf(" ");
if( j == length - 1)
printf("#\n");
}
}
for( i = 0; i < length + 2; i++)
printf("#\n");
}
void Input()
{
}
void Logic()
{
}
int main(void)
{
Game();
while (!gameEnd)
{
Display();
Input();
Logic();
Sleep(10);
}
return 0;
}
First avoid to make semicolon after the #define, you will get compilation error when you try to pass your constant TRUE to a function.
To have correct display, you should remove the "\n" from printf of first and last for loop of the function Display. And Add printf("\n") just after the for loop. It should be:
void Display()
{
int i;
int j;
system("cls");
for( i = 0; i < length + 2; i++)
printf("#");
printf("\n");
for( i = 0; i < height; i++)
{
for(j = 0; j < length; j++)
{
if( j == 0 )
printf("#");
printf(" ");
if( j == length - 1)
printf("#\n");
}
}
for( i = 0; i < length + 2; i++)
printf("#");
}
In case you want to display a character "*" in position (x, y), you just need to change:
printf(" ");
by:
if (y == i && x == j)
printf("*");
else
printf(" ");

Resources