How to make cross sign based on user-input in C - c

Hi i'm currently practicing using c in my school, i have a problem to make cross-sign in C based on user-input, my code only work properly when the height is 11
first i made non-user-input code when height=11 (well this is my actual assgnment) and then make some changes here and there
thanks for your answer
#include <stdio.h>
int main(void)
{
int n, i = 1, j = 9, l = 0, height;
char ch = '#';
printf("Enter the height of cross sign : ");
scanf("%d",&height);
n = (height / 2.0) - 0.5;
while (i <= n)
{
printf("%*c%*c\n", i, ch, (2*n - 2*i + 1), ch);
i++;
}
while (n < j)
{
printf("%*c%*c\n", (j - n), ch, (j - n - 1 + l), ch);
n++;
l += 3;
}
return 0;
}

Firstly your code has some compiler error. You missed some semicolons. Secondly your code works fine till 11 cause of the CPL. You can read about it in the link given below :https://en.wikipedia.org/wiki/Characters_per_line

You don't need to see where's the middle, if you have two variables doing the opposite, like one decreasing and the other increasing at the same time.
this is my code to that problem resolved:
int height, i , j, l;
char ch = '#', sp = ' ';
printf("Enter the height of cross sign : ");
scanf("%d",&height);
j=height;
for(i=1;i<=height;i++)
{
for(l=1;l<=height;l++)
{
if(l==i||l==j)
{
printf("%c", ch); //if it's suppose to print '#'
}
else
{
printf("%c", sp); //if it's suppose to print space - ' '
}
}
j--;
printf("\n");
}
return 0;

Related

Is it possible to simplify this algorithm so that it only uses 1 loop and 2 variables?

Is it possible to get the same results as this code using only a and b?
I'm trying to calculate c from a and b to avoid using a third variable, but I can't find a solution.
#include <stdio.h>
#include <stdlib.h>
const int LENGTH = 20;
int main()
{
char arr[LENGTH];
for (int a = 0, b = 1, c = 0; c < LENGTH; c++) {
if (a < b) {
arr[c] = '*';
a++;
} else {
arr[c] = ' ';
a = 0;
b++;
}
}
printf(arr);
return EXIT_SUCCESS;
}
Code result : * ** *** **** *****
In the event that checking if a number is triangular by linking or writing some sort of sqrt() function is not a solution that you find acceptable:
Each group of **... in the final string has a ' ' at the end, so the shortest segment in the string is "* ", which is 2 chars long.
The c in your loop is the index of the char array that this iteration should write to, the a is the index inside the current group of '*'s, and b is length of the current group of '*'s less one (since we want to count the spaces). Directly before the if clause in your for loop, it can be said that c is the sum from 2 to b plus a.
In other words, if a=0, and b=1, then c=0, because the sum from 2 to 0 is 0, plus 0 is 0.
If a=3, and b=4, then c= (2+3+4) + 3 = 12.
This means that you could write your code like this:
#include <stdio.h>
const int LENGTH = 20;
int sumFromTwo(int in){ //Recursive function to calculate sigma(2:in)
if(in < 2)
return 0;
else
return in + sumFromTwo(in - 1);
}
int main()
{
char arr[LENGTH + 1]; //Extra byte for null-terminator
for (int a = 0, b = 1; sumFromTwo(b) + a < LENGTH ; ) {
if (a < b) {
arr[sumFromTwo(b) + a] = '*';
a++;
} else {
arr[sumFromTwo(b) + a] = ' ';
a = 0;
b++;
}
}
arr[LENGTH] = '\0'; //Always null-terminate your strings
printf(arr);
return EXIT_SUCCESS;
}
But using recursion to avoid using a variable that is almost certainly going to be optimized into a register anyway is not going to save your computer any resources, least of all RAM, so it is definitely cleaner to do it the way you did in your question (but please null-terminate your string before passing it to your choice of printf or puts).

Finding Substring in 2D Array(Puzzle)

I have been trying to make a word puzzle(without using any library functions)like you would find in a newspaper like the following:
15 rows 12 colums
X T Z M Q Y K C E C F H -->12 chars
S H O U T E X O E A P I
X G T L Q B E L T N F K
'
'
'
as you can see in the second row there is the word SHOUT. Now the puzzle is designed so that the user can input any sort of char set they want line by line.
What I want to do is when a word is searched (like SHOUT) I would return its starting index. The index I imagined will start at 0 and end at 180, as 12*15=180 like this to be clear:
X T Z M Q Y K C E C F H
0 1 2 3 4 5 6 7 8 9 10 11
S H O U T E X O E A P I
12 13 14 15 16 17 18 19 20 21 22 23
'
'
'
'''''''''''''''''''179
Its hard to explain it without a picture, I hope you understand.
Now the tricky thing is words can be in every direction (up to down, down to up, left to right, right to left). I have written most of the code but keep getting errors and it only can check if the word exists from left to right.
#include <stdio.h>
#define COLUNM 12
#define ROW 15
int computeLength (char str[50]) {
int i;
for (i = 0; str[i] != '\0'; ++i) {
}
return i;
}
int findString(char matrix[ROW][COLUNM], char string[], int length) {
int i = 0, j, k = 0, searchlenght = 0;
length = computeLength(string);
for (j = 0; j < ROW; j++) {
if (matrix[j][k] == string[k]) {
searchlenght++;
}
}
i++;
if (searchlength == length) {
return i;
}
}
int main() {
int i, j = 0;
char matrix[ROW][COLUNM];
char string[50];
int b = 1;
for (i = 0; i < ROW; i++) {
printf("Enter line %d of the puzzle :\n", i + 1);
scanf("%s", &matrix[j][i]);
j++;
}
while (b > 0) {
printf("Enter the string to be searched in the puzzle:\n");
scanf("%s", &string[50]);
if ((string[0] != 'q') || (string[0] != 'Q')) {
b = 0;
}
}
return 0;
}
I don't think this is so hard to implement with python but I'm so unfamiliar with C that I keep getting errors and warnings.
Only part that needs work is findString function. Don't bother with input as I will test it myself.
Could you please help?
**The only part that does not work is length=computeLength(str1); thşs when I enter computeLength("Shout") it returns 5 but in this piece of code it returns 2 which messes up the result **
int findString(char matrix[ROW][COLUNM],char str1[],int length){
int i,j,wordcounting;
int true=1;
length=computeLength(str1);
printf("%d",length);
for(j=0;j<ROW;j++){
if(matrix[i][j]==str1[0]){
for(wordcounting=1;wordcounting<length;wordcounting++){
if((matrix[i][j+wordcounting]!=str1[wordcounting])){
true=0;
break;
}
}
}
i++;}
if(true==1){return (i-length);}
}
When I say printf("%d",computeLength(string)); even before ı input a string it becomes 2
Here is a loooooooog answer where I explain the more I can your problems, how to solve them, and finally how to implement the search step by step up to a final solution.
Have a good reading !
There a lot of problems in your code, first it cannot be compiled.
The line 29 is invalid, replace
int findString(char matrix[ROW][COLUNM],char string[15],int computeLength(string[15])){
by
int findString(char matrix[ROW][COLUNM], char string[15])
Note also the size 15 is useless you can use char string[] or char * string for the parameter string
The line 39 is invalid, replace
if(count==computeLength(string[15])){
by
if(count==computeLength(string)){
Now you can compile your program, but this not enough.
Some problems in main.
You exchanged the indexes in the line
scanf("%s",&matrix[j][i]);
It can be replaced by
scanf("%s",&matrix[i][0]);
(I used 0 rather than j because it is more clear, that does not ask us to check j values 0)
But this is not enough, scanf can read more than COLUNM characters if the input is invalid, and even the input is 12 characters as you expect you forget scanf will also write the null character finishing the string, so it writes 13 characters.
A way is to read in string which is longer than COLUMN more 2 and check the length of the input string. So your for can be replaced by :
for(i = 0 ; i < ROW ; i++)
{
printf("Enter line %d of the puzzle :\n",i+1);
if ((scanf("%49s", string) != 1) ||
(strlen(string) != COLUMN)) {
puts("invalid line");
return -1;
}
memcpy(&matrix[i][0], string, COLUMN);
i++;
}
Note also at the end i is incremented rather than j.
In the while loop
scanf("%s",&string[50]);
is invalid because it will place the result after string, the index must be 0 and in fact you can just give string.
As before if the input as more than 49 characters scanf will write out of string, so do
scanf("%49s", string);
If you want to allow to search a string of 50 characters without counting the final null character you have to size it with 51 and replace 49 by 50.
Out of printing and reading the while loop does nothing, it is very probable you wanted to call findString in it and to write the returned value, until the first read character is q or Q. For instance :
for (;;) {
puts("Enter the string to be searched in the puzzle:");
if ((scanf("%49s", string) != 1) || (string[0] =='q') || (string[0] == 'Q'))
break;
printf("position in the puzzle: %d\n", findString(matrix, string));
}
At the end of main the interest of that line is obscure :
printf("%d",computeLength("küfür"));
In printPuzzle you missed to introduce a newline after you print PUZZLE, you can just replace printf by puts. Note it is useless to ask printf to search for % etc while you know there is none.
In findString
A first problem is you only return a value if count==computeLength(string) is true, you need to always to return a value. Typically you can return -1 if the string is not in the puzzle, so
return (count==computeLength(string)) ? i : -1;
but this is wrong too, and for two reasons :
when you reach the test i always value 180, not the position where the string was
this is not because count==computeLength(string) is true that the string was found because of the way you used to increment count and the next error :
You do not search correctly the string in the puzzle because your first loop on i goes though the string (string[i]), and worst will access to 180 characters in it while its length is only 49 (without the final null character). You also do not stop to search even you find the string. And in your algorithm you forget the characters of string must be placed consecutively in the matrix, you each time you (wrongly) find a character of the string anywhere in the matrix you increment count.
Just considering you search the string horizontally from left to right :
The loop on string must be the more embedded loop to check its characters are consecutive in the matrix.
You have one loop on the row an one on the column, this is useless and just make the job complex for nothing. Because matrix is an array the character at matrix[r][COLUMN] is the character at matrix[r+1][0], that means you can go through matrix like it is a string of ROW*COLUMN characters.
I let you rewrite findString, it is like strstr except you return the index or -1 rather than the address of the substring or NULL
[edit with proposal for the search functions]
To explain I will use that small matrix more easy to look at :
#define COLUMN 3
#define ROW 5
char Matrix[ROW][COLUMN] = { { 'a', 'b' , 'c' },
{ 'd', 'e' , 'f' },
{ 'g', 'h' , 'i' },
{ 'j', 'k' , 'l' },
{ 'm', 'n' , 'o' } };
Let start with searching from left to right, this is similar to the classic strstr function except the return value and there is a rollback at the end of the matrix. Let decide the value is -1 if the string is not found else the position of its first character times 1000 more the position of its last character. The definition can be :
int search_left2right(char * matrix, char * word)
{
int i;
for (i = 0; i != ROW*COLUMN; ++i) {
int j = i;
char * w = word;
while (*w == matrix[j]) {
if (!*++w)
return i * 1000 + j;
if (++j == ROW*COLUMN)
j = 0;
}
}
return -1;
}
Compilation and execution with that main :
int main()
{
printf("%d\n", search_left2right((char *) Matrix, "cde"));
printf("%d\n", search_left2right((char *) Matrix, "noa"));
printf("%d\n", search_left2right((char *) Matrix, "cdf"));
return 0;
}
pi#raspberrypi:/tmp $ ./a.out
2004
13000
-1
pi#raspberrypi:/tmp $
2004 if for 2 and 4, 13000 if for 13 and 0, the string is not found in the last case, this is ok
Searching from right to left.
A first obvious way is to reuse the previous function and to reverse the string before to search it. In case the string is found in the result the position of the first and last characters are just reversed too.
An other way is to iterate on the string to search in the reverse order, let choose that way.
Searching from right to left or from left to right.
To indicate the direction the parameter wstep is added and values 1 for left to right, else -1. The definition can be :
/* manual strlen, you want to define all string functions */
int strLen(char * s)
{
char * p = s;
while (*p)
p += 1;
return p - s;
}
int search_horiz(char * matrix, char * word, int wstep)
{
int i;
int wbegin = (wstep == 1) ? 0 : strLen(word) - 1;
int wend = (wstep == 1) ? strLen(word) - 1 : 0;
for (i = 0; i != ROW*COLUMN; ++i) {
int j = i;
int k = wbegin;
while (word[k] == matrix[j]) {
if (k == wend)
return (wstep == 1) ? i * 1000 + j : j * 1000 + i;
k += wstep;
if (++j == ROW*COLUMN)
j = 0;
}
}
return -1;
}
Compilation and execution with that main :
int main()
{
printf("%d\n", search_horiz((char *) Matrix, "cde", 1));
printf("%d\n", search_horiz((char *) Matrix, "edc", -1));
printf("%d\n", search_horiz((char *) Matrix, "noa", 1));
printf("%d\n", search_horiz((char *) Matrix, "aon", -1));
printf("%d\n", search_horiz((char *) Matrix, "cdf", 1));
printf("%d\n", search_horiz((char *) Matrix, "fdc", -1));
return 0;
}
pi#raspberrypi:/tmp $ gcc -g -Wall m.c
pi#raspberrypi:/tmp $ ./a.out
2004
4002
13000
13
-1
-1
pi#raspberrypi:/tmp $
Searching from top to bottom.
When we search from left to right we compare the characters from to string with the consecutive characters in the matrix (step is 1), more the roll back.
To search from top to bottom we do not have to look consecutive characters in the matrix, we want to stay in the same vertical so the step is COLUMN. Of course this is not the case when we are on the last line, in that case we go back on the first line and move to the right, except from the last character of the matrix where we have to rollback to the first character. The definition can be :
int search_top2down(char * matrix, char * word)
{
int i;
for (i = 0; i != ROW*COLUMN; ++i) {
int j = i;
char * w = word;
while (*w == matrix[j]) {
if (!*++w)
return i * 1000 + j;
if ((j += COLUMN) >= ROW*COLUMN)
j = (j - ROW*COLUMN + 1) % COLUMN;
}
}
return -1;
}
Compilation and execution with that main :
int main()
{
printf("%d\n", search_top2down((char *) Matrix, "dgj"));
printf("%d\n", search_top2down((char *) Matrix, "knc"));
printf("%d\n", search_top2down((char *) Matrix, "oad"));
return 0;
}
pi#raspberrypi:/tmp $ gcc -g -Wall m.c
pi#raspberrypi:/tmp $ ./a.out
3009
10002
14003
pi#raspberrypi:/tmp $
Searching from left to right or from top to bottom
But comparing search_left2right and search_top2down we can see they have almost the same definition, the only change is the value of the step in the matrix and the correction when the step cannot be applied alone. So it is possible to have:
int search_left2right_top2down(char * matrix, char * word, int step, int correct)
{
int i;
for (i = 0; i != ROW*COLUMN; ++i) {
int j = i;
char * w = word;
while (*w == matrix[j]) {
if (!*++w)
return i*100 + j;
if ((j += step) >= ROW*COLUMN)
j = (j - ROW*COLUMN + correct) % COLUMN;
}
}
return -1;
}
To do left to right step is 1 and correct is 0, to do top to bottom step is COLUMN and correct is 1.
Searching in all the four directions
The needed modification to search from bottom to top from top to bottom are like it was to search right to left from left to right.
That means we can have easily only one search function managing left to right, right to left, top to bottom and bottom to top. For instance :
int search(char * matrix, char * word, int wstep, int step, int correct)
{
int i;
int wbegin = (wstep == 1) ? 0 : strLen(word) - 1;
int wend = (wstep == 1) ? strLen(word) - 1 : 0;
for (i = 0; i != ROW*COLUMN; ++i) {
int j = i;
int k = wbegin;
while (word[k] == matrix[j]) {
if (k == wend)
return (wstep == 1) ? i * 1000 + j : j * 1000 + i;
k += wstep;
if ((j += step) >= ROW*COLUMN)
j = (j - ROW*COLUMN + correct) % COLUMN;
}
}
return -1;
}
With that main compilation and execution :
int main()
{
printf("%d\n", search((char *) Matrix, "cde", 1, 1, 0));
printf("%d\n", search((char *) Matrix, "noa", 1, 1, 0));
printf("%d\n", search((char *) Matrix, "cdf", 1, 1, 0));
putchar('\n');
printf("%d\n", search((char *) Matrix, "edc", -1, 1, 0));
printf("%d\n", search((char *) Matrix, "aon", -1, 1, 0));
printf("%d\n", search((char *) Matrix, "fdc", -1, 1, 0));
putchar('\n');
printf("%d\n", search((char *) Matrix, "dgj", 1, COLUMN, 1));
printf("%d\n", search((char *) Matrix, "knc", 1, COLUMN, 1));
printf("%d\n", search((char *) Matrix, "oad", 1, COLUMN, 1));
putchar('\n');
printf("%d\n", search((char *) Matrix, "jgd", -1, COLUMN, 1));
printf("%d\n", search((char *) Matrix, "cnk", -1, COLUMN, 1));
printf("%d\n", search((char *) Matrix, "dao", -1, COLUMN, 1));
return 0;
}
pi#raspberrypi:/tmp $ gcc -Wall m.c
pi#raspberrypi:/tmp $ ./a.out
2004
13000
-1
4002
13
-1
3009
10002
14003
9003
2010
3014
pi#raspberrypi:/tmp $
Let notice to give the 3 parameters to indicate how to process is not a pretty way, I used them because I considered it was better to have them to explain, but because there are always the same it is easy to improve :
#include <stdio.h>
#define COLUMN 3
#define ROW 5
/* manual strlen, you want to define all string functions */
int strLen(const char * s)
{
const char * p = s;
while (*p)
p += 1;
return p - s;
}
typedef struct SearchParameters {
int wstep;
int step;
int correct;
} SearchParameters;
const SearchParameters Left2Right = { 1, 1, 0 };
const SearchParameters Right2Left = { -1, 1, 0 };
const SearchParameters Top2Bottom = { 1, COLUMN, 1 };
const SearchParameters Bottom2Top = { -1, COLUMN, 1 };
int search(const char * matrix, const char * word, SearchParameters how)
{
int i;
int wbegin = (how.wstep == 1) ? 0 : strLen(word) - 1;
int wend = (how.wstep == 1) ? strLen(word) - 1 : 0;
for (i = 0; i != ROW*COLUMN; ++i) {
int j = i;
int k = wbegin;
while (word[k] == matrix[j]) {
if (k == wend)
return (how.wstep == 1) ? i * 1000 + j : j * 1000 + i;
k += how.wstep;
if ((j += how.step) >= ROW*COLUMN)
j = (j - ROW*COLUMN + how.correct) % COLUMN;
}
}
return -1;
}
/* */
typedef struct TestCase {
const char * str;
const SearchParameters * how;
const char * strHow;
} TestCase;
void test(const char (*m)[3], const TestCase * tc)
{
int r = search((char *) m, tc->str, *(tc->how));
if (r == -1)
printf("cannot found '%s' in '%s'\n", tc->str, tc->strHow);
else
printf("'%s' found in '%s', start at %d, end at %d\n",
tc->str, tc->strHow, r / 1000, r % 1000);
}
int main()
{
static const char matrix[ROW][COLUMN] = { { 'a', 'b' , 'c' },
{ 'd', 'e' , 'f' },
{ 'g', 'h' , 'i' },
{ 'j', 'k' , 'l' },
{ 'm', 'n' , 'o' } };
static const TestCase tests[] = {
{ "cde", &Left2Right, "Left2Right" },
{ "noa", &Left2Right, "Left2Right" },
{ "cdf", &Left2Right, "Left2Right" },
{ "edc", &Right2Left, "Right2Left" },
{ "aon", &Right2Left, "Right2Left" },
{ "fdc", &Right2Left, "Right2Left" },
{ "dgj", &Top2Bottom, "Top2Bottom" },
{ "knc", &Top2Bottom, "Top2Bottom" },
{ "oad", &Top2Bottom, "Top2Bottom" },
{ "jgd", &Bottom2Top, "Bottom2Top" },
{ "cnk", &Bottom2Top, "Bottom2Top" },
{ "dao", &Bottom2Top, "Bottom2Top" }
};
int t;
for (t = 0; t != sizeof(tests) / sizeof(TestCase); t += 1)
test(matrix, &tests[t]);
return 0;
}
Compilation and execution:
pi#raspberrypi:/tmp $ gcc -Wall mm.c
pi#raspberrypi:/tmp $ ./a.out
'cde' found in 'Left2Right', start at 2, end at 4
'noa' found in 'Left2Right', start at 13, end at 0
cannot found 'cdf' in 'Left2Right'
'edc' found in 'Right2Left', start at 4, end at 2
'aon' found in 'Right2Left', start at 0, end at 13
cannot found 'fdc' in 'Right2Left'
'dgj' found in 'Top2Bottom', start at 3, end at 9
'knc' found in 'Top2Bottom', start at 10, end at 2
'oad' found in 'Top2Bottom', start at 14, end at 3
'jgd' found in 'Bottom2Top', start at 9, end at 3
'cnk' found in 'Bottom2Top', start at 2, end at 10
'dao' found in 'Bottom2Top', start at 3, end at 14
pi#raspberrypi:/tmp $
Just looking at the compile error mentioned (and only the compile error), I suggest you do something like this:
int findString(char matrix[ROW][COLUNM],char string[15])
{
int length = computeLength(string);
...
}
You can't have the way you declared the function like what you did. Now slight further recommendation...
There is already a C function that can compute C string lengths:
#include <string.h>
...
const char* string = "hello";
int length = strlen(string);
...

Replace a character with another character + Setting a tie game

This is for Homework
I have to create a game of TicTacToe for a project and I have two issues. Also I apologize if I'm violating a rule by having two questions within one post, If it's not allowed then I'd appreciate someone notifying me in the comments and I'll go ahead and break this into two separate posts. I'll post my code then ask my questions following the code.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
char table[3][3];
void clear_table();
void player1_move();
void player2_move();
void the_matrix(); // Like the movie
char check_three();
int main() {
srand(time(NULL));
char win;
printf("This program plays the game of Tic Tac Toe.\n");
win = ' ';
clear_table();
do {
the_matrix(); // Like the movie
player1_move();
win = check_three(); // Check win for player 1
if (win != ' ')
break;
player2_move();
win = check_three(); // Check win for player 2
}
while (win == ' ');
the_matrix(); // Shows the final move+Like the movie
if (win == 'O')
printf("Congratulations, Player 1 wins!\n");
else
printf("Congratulations, Player 1 lost!\n");
// the_matrix (); //Shows the final move+Like the movie
return 0;
}
void clear_table() {
// Creates empty spaces for the user and computer to enter stuff in
int i, j, k;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++)
// for(l = 0; k < 3; j++)
table[i][j] = ' ';
}
}
void player1_move() {
// Moves that player 1 can and can't make
int x, y, z;
printf("Player 1 enter your selection[row, col]: ");
scanf("%d, %d", &x, &y);
x--;
y--;
// z--;
if (table[x][y] != ' ') {
printf("Space already taken, please try again.\n");
player1_move();
}
else
table[x][y] = 'O'; // O goes first for some reason
}
void player2_move() {
// Needs work!!
// Call srand in the main
int a = rand() % 3;
int b = rand() % 3;
// Make it so the game would end in a tie when possible
for (a = rand() % 3; a < 3; a++) {
for (b = rand() % 3; b < 3;
b++) // For loops causing issues in randomization?
// for(c = 0; c < 3; c++)
if (table[a][b] == ' ')
break;
if (table[a][b] == ' ') // Checks the rows and columns
break;
}
if (a * b == 9)
**Kinda works ? ** {
printf("Game Over, No Player Wins\n");
exit(0);
}
else
table[a][b] = 'X';
}
void the_matrix() { // Like the movie
**Get rid of the underscores **
int m;
printf("The current state of the board:\n");
for (m = 0; m < 3; m++) {
printf("%c_ %c_ %c_\n", table[m][0], table[m][1], table[m][2]);
}
printf("\n");
}
char check_three() {
int w;
// char table[3][3];
for (w = 0; w < 3; w++) {
if (table[w][0] == table[w][2] && table[w][0] == table[w][1])
return table[w][0]; // Row Check
}
for (w = 0; w < 3; w++) {
if (table[0][w] == table[2][w] && table[0][w] == table[1][w])
return table[0][w]; // Col Check
}
if (table[0][0] == table[1][1] && table[1][1] == table[2][2])
return table[0][0];
if (table[0][2] == table[1][1] && table[1][1] == table[2][0])
return table[0][2]; // Diag Check
return ' ';
}
First Question
So my first question is with a draw game. On the player two function I have a snip of code set to determine a draw game. Initially I assumed that if the X's and O's were to multiply to 9 then that would mean that the board would be filled up then that would result in a draw game. [This is within my third function - player2_move near the end of the function] It kind of works, but sometimes the program just preemptively ends the game. It's a bit hard to test it because the computers moves are randomized and most of the times I've tried, I ended up winning accidentally. My question is what would I need to do to set up my program to essentially have a better way of determining a draw game.
Second Question
On my 4th function called the_matrix I need help with formatting. The assignment requires the format to be a little like this where if I were to enter in the coordinates 1,1 then the board would look like this:
O _ _ with the proceeding lines near the bottom to be blank. However as my program is right now, it looks like this:
O_ _ _
What I want to do is swap or replace the underscore with the user's input. Not entirely sure how to do that and any help would be appreciated.
I apologize if I violated any rules for stackoverflow by having two questions in one and I'm also sorry for this huge post.

My executable stops running when I try to runmy program in Eclipse CDT

After I build my project, I seem to be getting this message where it says that my program Cyber Dojo 1 has stopped working. This is shown below:
Now there are a few resources online, including:
This SO post, which has one answer that has not been accepted. The answer is not valid, as I do not have any arguments for my program.
This forum post itself on the Eclipse Community Forums. This has a few good suggestions, especially the one that relates to changing MinGW's linker flags. However, this would apply to a C++ program and not a C program. This is also a post that deals with the same problem, but once again, for C++.
And that is why I am currently looking for a solution for this problem for a C program on my Eclipse CDT.
Here is my code:
//Checking number as input
static void isNotValidCharacter1(void)
{
assert(answer('3') == NULL);
}
//Checking special character
static void isNotValidCharacter2(void)
{
assert(answer('!') == NULL);
}
//Checking lowercase letter
static void isNotValidCharacter3(void)
{
assert(answer('c') == NULL);
}
static void validCharacter(char **sample_answer)
{
int i, j;
for (i = 1; i < 11; i++) {
for (j = 1; j < 11; j++) {
assert((answer('F'))[i][j] == sample_answer[i][j]);
}
}
}
//Random Number Corner Checks Follow:
// Randomly creates a number/ character and checks the leftmost and rightmost corner characters
// as the character itself
static char psuedoRandomNumberGeneratedCharacterCheck1(void)
{
// Creating the random number between 65 and 90
int rn;
srand(time(NULL));
rn = (rand() % 25) + 65;
int distA = rn - 65;
//converting it to a character
char c_rn = (char)rn;
//checking the leftmost and rightmost corner characters
assert(answer(rn)[distA][0] == c_rn);
assert(answer(rn)[distA][distA*2] == c_rn);
return c_rn;
}
// Randomly creates a number/ characters and the checks the uppermost and lowermost corner characters
// corners as 'A'
static char psuedoRandomNumberGeneratedCharacterCheck2(void)
{
// Creating the random number between 65 and 90
int rn;
srand(time(NULL));
rn = (rand() % 25) + 65;
int distA = rn - 65;
//converting it to a character
char c_rn = (char)rn;
//checking the uppermost and lowermost corner characters
assert(answer(rn)[0][distA] == 'A');
assert(answer(rn)[distA*2][distA] == 'A');
return c_rn;
}
static void validCharacterA(void)
{
char **aDiamond = answer('A');
aDiamond[0][0] = 'A';
}
int main(void)
{
//Not valid character tests
isNotValidCharacter1();
puts("Number not accepted");
puts("special pause for debugging");
isNotValidCharacter2();
puts("Special Character not accepted");
isNotValidCharacter3();
puts("lowercase not accepted");
//Psuedorandom Tests
char prc1 = psuedoRandomNumberGeneratedCharacterCheck1();
printf("random character '%c' chosen and the leftmost and rightmost corner characters", prc1);
char prc2 = psuedoRandomNumberGeneratedCharacterCheck2();
printf("random character '%c' chosen and the leftmost and rightmost corner characters", prc2);
// Acid Test for the letter 'F'
//Square of 11 letters declared
char **Fanswer = malloc(11 * sizeof(*Fanswer));
int i;
for (i =0; i <11; i++) {
Fanswer[i] = malloc(11 * sizeof(char));
}
strcpy( Fanswer[0], " A ");
strcpy( Fanswer[1], " B B ");
strcpy( Fanswer[2], " C C ");
strcpy( Fanswer[3], " D D ");
strcpy( Fanswer[4], " E E ");
strcpy( Fanswer[5], "F F");
strcpy( Fanswer[6], " E E ");
strcpy( Fanswer[7], " D D ");
strcpy( Fanswer[8], " C C ");
strcpy( Fanswer[9], " B B ");
strcpy(Fanswer[10], " A ");
validCharacter(Fanswer);
puts("answer for F is correct");
validCharacterA();
puts("Answer for A is correct");
//All tests have passed and the end of the program
puts("All tests passed");
}
And my program for answer() is as follows:
char** answer(char c)
{
if (check(c)) {
printf("\n");
} else {
printf("Not a valid character\n");
return NULL;
}
//--------------------------------------------------------------------------------------------------------
// Preprocessing
//--------------------------------------------------------------------------------------------------------
//processing declarations
int ascii = (int)c;
int distA = ascii - 'A';
//Number of Rows and Columns
int n = ( distA * 2 ) + 1;
//Declare the column of pointers
char **diamond = malloc(n * sizeof(*diamond));
//Declare the row of characters
// 2D array declared here to save on computation in situations where characters are not valid
int i;
for (i=0; i<n; i++) {
diamond[i] = malloc(n * sizeof(char));
}
//--------------------------------------------------------------------------------------------------
// Processing
//--------------------------------------------------------------------------------------------------
//Fill in the Array
if (n == 1) {
diamond[0][0] = c;
} else {
diamond[distA][0] = c;
diamond[distA][distA*2] = c;
for (i = 1; i <= distA; i++) {
diamond[distA-i][i] = (char)(ascii - i);
diamond[distA-i][(distA*2)-i] = (char)(ascii - i);
diamond[distA+i][i] = (char)(ascii - i);
diamond[distA+i][(distA*2)-i] = (char)(ascii - i);
}
}
//-------------------------------------------------------------------------------------------------
// Postprocessing
//---------------------------------------------------------------------------
return diamond;
}
If you are a beginer with Eclipse and you don't know how to use a debugger, you can look some tutorial.
https://www.youtube.com/watch?v=azInZkPP56Q
But even after this tutorial you have difficulty to making your debuger works (because sometimes it depends how installed your Eclipse, your compiler and other things), you can try to put a big part of your code in comment and see if the problem is gone. And little by little reduce the amount of code you put in comment. When the bug reapear it means it's somewhere inside the part you removed the comment recently.
The last method is not the best way to debug your program but can be usefull for beginners and give you another alternative if you have difficulty to use your debugger.

Need some suggestions on how to print a histogram more neatly

I'm writing a program that will read input and then give back a histogram of the character count from K & R - Ex. 1.13
Any suggestions on how I can improve my code? Does it matter whether or not if I test for status in condition or out first? I have noticed in my examples people test to see if c is a blank or tab first.
I think I need to revisit my histogram. It doesn't really scale the results. It just draws a hyphen based on the length.
Revised to make a little bit more readable I think.
// Print a histogram of the length of words in it's input.
#include <stdio.h>
#define IN 1
#define OUT 2
#define MAX 99
int main(){
int c; // the character
int countOfLetters = 0;
int insideWord = OUT;
int frequencyOfLengths[MAX];
int longestWordCount = 0;
int i, j; // Counters
for (i = 0; i < MAX; i++){
frequencyOfLengths[i] = 0;
}
while ((c = getchar()) != EOF){
if (c == ' ' || c == '\n' || c == '\t'){
if (insideWord == IN){
if (countOfLetters > MAX){
return 1;
}
++frequencyOfLengths[countOfLetters];
if (countOfLetters >= longestWordCount) longestWordCount = countOfLetters;
}
countOfLetters = 0;
}
else {
countOfLetters++;
insideWord = IN;
}
}
for (i = 1; i <= longestWordCount; i++){
printf("%3i : %3i ", i, frequencyOfLengths[i]);
for (j = 0; j < frequencyOfLengths[i]; j++){
printf("*");
}
printf("\n");
}
return 0;
}
Definitely scale results, check out my Character Histogram that does a horizontal scaling histogram.
Also, you could benefit a y-axis label. It's hard to tell which bar is for which kind of word length. I have no idea which bar is for what word length.
I added this code right before you display the histogram, it basically halves every value, which does throw off your bar number labels. You can figure it out!
// Iterates and tells us the most frequent word length
int mostFrequent = 0;
for (i = 1; i < MAXWORD; i++)
if (charCount[i] > mostFrequent)
mostFrequent = charCount[i];
// If the bar will be too big, cut every value in half
while (mostFrequent > 60) {
for (i = 1; i < MAXWORD; i++)
if (charCount[i] > 0) {
charCount[i] /= 2;
charCount[i] |= 1;
}
// Check again to find the most frequent word length category
mostFrequent = 0;
for (i = 1; i < MAXWORD; i++)
if (charCount[i] > mostFrequent)
mostFrequent = charCount[i];
}
Honestly the bars are hard to read, maybe just use a single row of characters such as █ !
Great book so far, we're practically reading it together and are on the same page!
Cheers

Resources