I get error messages that I can't turn off [duplicate] - c

This question already has answers here:
Why can we not declare a variable after a switch case colon without using curly braces?
(3 answers)
Closed last month.
I got the following C code here and following error messages and just don't know how to solve it:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#pragma warning (disable: 4996)
#define MAX_ROWS 20
#define MAX_COLS 30
typedef struct {
char data[MAX_ROWS][MAX_COLS];
int rows;
int cols;
} Matrix;
char neighbor_count(Matrix* m, int row, int col) {
int count = 0;
for (int i = row - 1; i <= row + 1; i++) {
if (i < 0 || i >= m->rows) {
continue;
}
for (int j = col - 1; j <= col + 1; j++) {
if (j < 0 || j >= m->cols) {
continue;
}
if (m->data[i][j] == '*' && (i != row || j != col)) {
count++;
}
}
}
return count;
}
void check_cell(Matrix* m, int row, int col) {
char neighbors_count = neighbor_count(m, row, col);
char current_cell = m->data[row][col];
if (neighbors_count < 2) { //Die Zelle stirbt an Vereinsamung
m->data[row][col] = ' ';
}
else if (neighbors_count > 3 && current_cell == '*') { //Die Zelle stirbt an Übervölkerung
m->data[row][col] = ' ';
}
else if (neighbors_count == 3 && current_cell == ' ') { //Aus der toten Zelle wird eine neue lebende Zelle
m->data[row][col] = '*';
}
else if (neighbors_count == 2 || neighbors_count == 3) { //Die Zelle lebt weiter
m->data[row][col] = '*';
}
}
void load_from_file(Matrix* m, const char* filename) {
FILE* f = fopen(filename, "r");
if (f == NULL) {
printf("File not found\n");
exit(-1);
}
int row_idx = 0;
char ch;
while ((ch = fgetc(f)) != EOF && row_idx < MAX_ROWS) {
if (ch == '\n') {
row_idx++;
continue;
}
m->data[row_idx][m->cols] = ch;
m->cols++;
}
m->rows = row_idx;
fclose(f);
}
void randomize(Matrix* m, int percent) {
m->rows = MAX_ROWS;
m->cols = MAX_COLS;
int cells = (m->rows * m->cols) * (percent / 100.0f);
srand(time(NULL));
while (cells > 0) {
int row = rand() % m->rows;
int col = rand() % m->cols;
if (m->data[row][col] == ' ') {
m->data[row][col] = '*';
cells--;
}
}
}
void print_matrix(Matrix* m) {
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++) {
printf("%c", m->data[i][j]);
}
printf("\n");
}
printf("\n");
}
void step(Matrix* m) {
Matrix m_tmp = *m;
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++) {
check_cell(&m_tmp, i, j);
}
}
*m = m_tmp;
}
int main() {
Matrix m;
// Menü zur Auswahl des Startzustands
printf("1. Aus Datei laden\n");
printf("2. Zufallszustand generieren\n");
int selection;
scanf("%d", &selection);
switch (selection) {
case 1: // Aus Datei laden
char filename[20];
printf("Bitte Dateinamen angeben: ");
scanf("%s", filename);
load_from_file(&m, filename);
break;
case 2: // Zufallszustand generieren
int percent;
printf("Prozentualer Anteil an lebenden Zellen: ");
scanf("%d", &percent);
randomize(&m, percent);
break;
default:
printf("Ungültige Eingabe\n");
return 0;
}
// Menü zur Auswahl der Animation
printf("1. Schrittweise Animation\n");
printf("2. Fließende Animation\n");
scanf("%d", &selection);
switch (selection) {
case 1: // Schrittweise Animation
while (1) {
print_matrix(&m);
step(&m);
getchar();
}
break;
case 2: // Fließende Animation
while (1) {
print_matrix(&m);
step(&m);
usleep(200000);;
}
break;
default:
printf("Ungültige Eingabe\n");
break;
}
return 0;
}
and this error messages
E1072 A declaration cannot have a label. CGoL Beleg Prog C:\Users\d-enk\OneDrive\Desktop\UNI MEDIENINFORMATIK\Programmierung\Vorlesung 1\CGoL Beleg Prog\CGoL Beleg Prog\Quelle.c 119
E1072 A declaration cannot have a label.. CGoL Beleg Prog C:\Users\d-enk\OneDrive\Desktop\UNI MEDIENINFORMATIK\Programmierung\Vorlesung 1\CGoL Beleg Prog\CGoL Beleg Prog\Quelle.c 125
LNK2019 Reference to unresolved external symbol "usleep" in function "main". CGoL Beleg Prog C:\Users\d-enk\OneDrive\Desktop\UNI MEDIENINFORMATIK\Programmierung\Vorlesung 1\CGoL Beleg Prog\CGoL Beleg Prog\Quelle.obj 1
LNK1120 1 unresolved external CGoL Beleg Prog C:\Users\d-enk\OneDrive\Desktop\UNI MEDIENINFORMATIK\Programmierung\Vorlesung 1\CGoL Beleg Prog\x64\Debug\CGoL Beleg Prog.exe 1

"A declaration cannot have a label" means that you cannot declare variables in the middle of a switch/case. You can solve this by adding a local compound statement:
case 1: // Aus Datei laden
{
char filename[20]; // this one was causing the problem
printf("Bitte Dateinamen angeben: ");
scanf("%s", filename);
load_from_file(&m, filename);
break;
}
Same thing with int percent;.
"Reference to unresolved external symbol "usleep"" means that the compiler can't find usleep. Most likely because it is obsolete in Windows. See this c++, usleep() is obsolete, workarounds for Windows/MingW?.

Related

The second generation is bugged (C, Conways Game of Life)

Hey so my problem is that the when I go run this code and choose to "Zufallstand generieren" (Generate random state) and then type in the "Prozentualer Anteil lebender Zellen" (Percentage of living cells) and then "Schrittweise Animation" or "Fließende Animation" (Step-by-step animation/Flowing animation) the second generation is absolute trash it does not match the first generation in one thing.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <string.h>
#pragma warning (disable: 4996)
#define MAX_ROWS 30
#define MAX_COLS 20
typedef struct {
char data[MAX_ROWS][MAX_COLS];
int rows;
int cols;
} Matrix;
char neighbor_count(Matrix *m, int row, int col) {
int count = 0;
for (int i = row - 1; i <= row + 1; i++) {
if (i < 0 || i >= m->rows) {
continue;
}
for (int j = col - 1; j <= col + 1; j++) {
if (j < 0 || j >= m->cols) {
continue;
}
if (m->data[i][j] == '*' && (i != row || j != col)) {
count++;
}
}
}
return count;
}
void check_cell(Matrix *m, int row, int col) {
char neighbors_count = neighbor_count(m, row, col);
char current_cell = m->data[row][col];
if (neighbors_count < 2) { //Die Zelle stirbt an Vereinsamung
m->data[row][col] = ' ';
}
else if (neighbors_count > 3 && current_cell == '*') { //Die Zelle stirbt an Übervölkerung
m->data[row][col] = ' ';
}
else if (neighbors_count == 3 && current_cell == ' ') { //Aus der toten Zelle wird eine neue lebende Zelle
m->data[row][col] = '*';
}
else if (neighbors_count == 2 || neighbors_count == 3) { //Die Zelle lebt weiter
m->data[row][col] = '*';
}
}
void load_from_file(Matrix *m, const char *filename) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
printf("File not found\n");
exit(-1);
}
int row_idx = 0;
char ch;
while ((ch = fgetc(f)) != EOF && row_idx < MAX_ROWS) {
if (ch == '\n') {
row_idx++;
continue;
}
#
m->data[row_idx][m->cols] = ch;
m->cols++;
}
m->rows = row_idx;
fclose(f);
}
void randomize(Matrix *m, int percent) {
memset(m->data, (int)' ', MAX_COLS * MAX_ROWS);
m->rows = MAX_ROWS;
m->cols = MAX_COLS;
int cells = (m->rows * m->cols) * (percent / 100.0f);
srand(time(NULL));
while (cells > 0) {
int row = rand() % m->rows;
int col = rand() % m->cols;
if (m->data[row][col] == ' ') {
m->data[row][col] = '*';
cells--;
}
}
}
void print_matrix(Matrix *m) {
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++) {
printf("%c", m->data[i][j]);
}
printf("\n");
}
printf("\n");
}
void step(Matrix *m) {
Matrix m_tmp = *m;
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++) {
check_cell(&m_tmp, i, j);
}
}
*m = m_tmp;
}
int main() {
Matrix m;
// Menü zur Auswahl des Startzustands
printf("1. Aus Datei laden\n");
printf("2. Zufallszustand generieren\n");
int selection;
scanf("%d", &selection);
switch (selection) {
case 1: // Aus Datei laden
{
char filename[20];
printf("Bitte Dateinamen angeben: ");
scanf("%s", filename);
load_from_file(&m, filename);
break;
}
case 2: // Zufallszustand generieren
{
int percent;
printf("Prozentualer Anteil an lebenden Zellen: ");
scanf("%d%%", &percent);
randomize(&m, percent);
break;
}
default:
printf("Ungültige Eingabe\n");
return 0;
}
// Menü zur Auswahl der Animation
printf("1. Schrittweise Animation\n");
printf("2. Fließende Animation\n");
scanf("%d", &selection);
switch (selection) {
case 1: // Schrittweise Animation
while (1) {
print_matrix(&m);
step(&m);
getchar();
}
break;
case 2: // Fließende Animation6
while (1) {
print_matrix(&m);
step(&m);
Sleep(2000);
}
break;
default:
printf("Ungültige Eingabe\n");
break;
}
return 0;
}
I tried to change the how the matrix works but without any success.
As others have mentioned, you are modifying the current matrix. You need to have a copy.
Ironically, your step function makes a copy. But, it still passes only one pointer to check_cell.
check_cell needs to have two matrix pointers. One for old/current state and another for new/future state.
Here are the changed functions:
void
check_cell(Matrix *mnew, Matrix *mold, int row, int col)
{
char neighbors_count = neighbor_count(mold, row, col);
char current_cell = mold->data[row][col];
do {
// Die Zelle stirbt an Vereinsamung
if (neighbors_count < 2) {
current_cell = ' ';
break;
}
// Die Zelle stirbt an Übervölkerung
if (neighbors_count > 3 && current_cell == '*') {
current_cell = ' ';
break;
}
// Aus der toten Zelle wird eine neue lebende Zelle
if (neighbors_count == 3 && current_cell == ' ') {
current_cell = '*';
break;
}
// Die Zelle lebt weiter
if (neighbors_count == 2 || neighbors_count == 3) {
current_cell = '*';
break;
}
} while (0);
mnew->data[row][col] = current_cell;
}
void
step(Matrix *m)
{
Matrix m_tmp = *m;
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++)
check_cell(m, &m_tmp, i, j);
}
}

How to get rid of error C1083: Cannot open include file: 'unistd.h'?

I'm trying to run this code on Visual Studio 2022, but it gives an error:
C1083: Cannot open include file: 'unistd.h': No such file or directory.
As I understood that the code was written for the UNIX system, but I would like to run it on Windows.
Snake game
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include<time.h>
#include<ctype.h>
#include <time.h>
#include <windows.h>
#include <process.h>
#include <unistd.h>
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
int length;
int bend_no;
int len;
char key;
void record();
void load();
int life;
void Delay(long double);
void Move();
void Food();
int Score();
void Print();
void gotoxy(int x, int y);
void GotoXY(int x, int y);
void Bend();
void Boarder();
void Down();
void Left();
void Up();
void Right();
void ExitGame();
int Scoreonly();
struct coordinate {
int x;
int y;
int direction;
};
typedef struct coordinate coordinate;
coordinate head, bend[500], food, body[30];
int main()
{
char key;
Print();
system("cls");
load();
length = 5;
head.x = 25;
head.y = 20;
head.direction = RIGHT;
Boarder();
Food(); //to generate food coordinates initially
life = 3; //number of extra lives
bend[0] = head;
Move(); //initialing initial bend coordinate
return 0;
}
void Move()
{
int a, i;
do {
Food();
fflush(stdin);
len = 0;
for (i = 0; i < 30; i++)
{
body[i].x = 0;
body[i].y = 0;
if (i == length)
break;
}
Delay(length);
Boarder();
if (head.direction == RIGHT)
Right();
else if (head.direction == LEFT)
Left();
else if (head.direction == DOWN)
Down();
else if (head.direction == UP)
Up();
ExitGame();
} while (!kbhit());
a = getch();
if (a == 27)
{
system("cls");
exit(0);
}
key = getch();
if ((key == RIGHT && head.direction != LEFT && head.direction != RIGHT) || (key == LEFT && head.direction != RIGHT && head.direction != LEFT) || (key == UP && head.direction != DOWN && head.direction != UP) || (key == DOWN && head.direction != UP && head.direction != DOWN))
{
bend_no++;
bend[bend_no] = head;
head.direction = key;
if (key == UP)
head.y--;
if (key == DOWN)
head.y++;
if (key == RIGHT)
head.x++;
if (key == LEFT)
head.x--;
Move();
}
else if (key == 27)
{
system("cls");
exit(0);
}
else
{
printf("\a");
Move();
}
}
void gotoxy(int x, int y)
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void GotoXY(int x, int y)
{
HANDLE a;
COORD b;
fflush(stdout);
b.X = x;
b.Y = y;
a = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(a, b);
}
void sleep(unsigned int mseconds)
{
clock_t goal = mseconds + clock();
while (goal > clock());
}
void load() {
int row, col, r, c, q;
gotoxy(36, 14);
printf("loading...");
gotoxy(30, 15);
for (r = 1; r <= 20; r++) {
sleep(200);//to display the character slowly
printf("%c", 177);
}
getch();
}
void Down()
{
int i;
for (i = 0; i <= (head.y - bend[bend_no].y) && len < length; i++)
{
GotoXY(head.x, head.y - i);
{
if (len == 0)
printf("v");
else
printf("*");
}
body[len].x = head.x;
body[len].y = head.y - i;
len++;
}
Bend();
if (!kbhit())
head.y++;
}
void Delay(long double k)
{
Score();
long double i;
for (i = 0; i <= (10000000); i++);
}
void ExitGame()
{
int i, check = 0;
for (i = 4; i < length; i++) //starts with 4 because it needs minimum 4 element to touch its own body
{
if (body[0].x == body[i].x && body[0].y == body[i].y)
{
check++; //check's value increases as the coordinates of head is equal to any other body coordinate
}
if (i == length || check != 0)
break;
}
if (head.x <= 10 || head.x >= 70 || head.y <= 10 || head.y >= 30 || check != 0)
{
life--;
if (life >= 0)
{
head.x = 25;
head.y = 20;
bend_no = 0;
head.direction = RIGHT;
Move();
}
else
{
system("cls");
printf("All lives completed\nBetter Luck Next Time!!!\nPress any key to quit the game\n");
record();
exit(0);
}
}
}
void Food()
{
if (head.x == food.x && head.y == food.y)
{
length++;
time_t a;
a = time(0);
srand(a);
food.x = rand() % 70;
if (food.x <= 10)
food.x += 11;
food.y = rand() % 30;
if (food.y <= 10)
food.y += 11;
}
else if (food.x == 0)/*to create food for the first time coz global variable are initialized with 0*/
{
food.x = rand() % 70;
if (food.x <= 10)
food.x += 11;
food.y = rand() % 30;
if (food.y <= 10)
food.y += 11;
}
}
void Left()
{
int i;
for (i = 0; i <= (bend[bend_no].x - head.x) && len < length; i++)
{
GotoXY((head.x + i), head.y);
{
if (len == 0)
printf("<");
else
printf("*");
}
body[len].x = head.x + i;
body[len].y = head.y;
len++;
}
Bend();
if (!kbhit())
head.x--;
}
void Right()
{
int i;
for (i = 0; i <= (head.x - bend[bend_no].x) && len < length; i++)
{
//GotoXY((head.x-i),head.y);
body[len].x = head.x - i;
body[len].y = head.y;
GotoXY(body[len].x, body[len].y);
{
if (len == 0)
printf(">");
else
printf("*");
}
/*body[len].x=head.x-i;
body[len].y=head.y;*/
len++;
}
Bend();
if (!kbhit())
head.x++;
}
void Bend()
{
int i, j, diff;
for (i = bend_no; i >= 0 && len < length; i--)
{
if (bend[i].x == bend[i - 1].x)
{
diff = bend[i].y - bend[i - 1].y;
if (diff < 0)
for (j = 1; j <= (-diff); j++)
{
body[len].x = bend[i].x;
body[len].y = bend[i].y + j;
GotoXY(body[len].x, body[len].y);
printf("*");
len++;
if (len == length)
break;
}
else if (diff > 0)
for (j = 1; j <= diff; j++)
{
/*GotoXY(bend[i].x,(bend[i].y-j));
printf("*");*/
body[len].x = bend[i].x;
body[len].y = bend[i].y - j;
GotoXY(body[len].x, body[len].y);
printf("*");
len++;
if (len == length)
break;
}
}
else if (bend[i].y == bend[i - 1].y)
{
diff = bend[i].x - bend[i - 1].x;
if (diff < 0)
for (j = 1; j <= (-diff) && len < length; j++)
{
/*GotoXY((bend[i].x+j),bend[i].y);
printf("*");*/
body[len].x = bend[i].x + j;
body[len].y = bend[i].y;
GotoXY(body[len].x, body[len].y);
printf("*");
len++;
if (len == length)
break;
}
else if (diff > 0)
for (j = 1; j <= diff && len < length; j++)
{
/*GotoXY((bend[i].x-j),bend[i].y);
printf("*");*/
body[len].x = bend[i].x - j;
body[len].y = bend[i].y;
GotoXY(body[len].x, body[len].y);
printf("*");
len++;
if (len == length)
break;
}
}
}
}
void Boarder()
{
system("cls");
int i;
GotoXY(food.x, food.y); /*displaying food*/
printf("F");
for (i = 10; i < 71; i++)
{
GotoXY(i, 10);
printf("!");
GotoXY(i, 30);
printf("!");
}
for (i = 10; i < 31; i++)
{
GotoXY(10, i);
printf("!");
GotoXY(70, i);
printf("!");
}
}
void Print()
{
//GotoXY(10,12);
printf("\tWelcome to the mini Snake game.(press any key to continue)\n");
getch();
system("cls");
printf("\tGame instructions:\n");
printf("\n-> Use arrow keys to move the snake.\n\n-> You will be provided foods at the several coordinates of the screen which you have to eat. Everytime you eat a food the length of the snake will be increased by 1 element and thus the score.\n\n-> Here you are provided with three lives. Your life will decrease as you hit the wall or snake's body.\n\n-> YOu can pause the game in its middle by pressing any key. To continue the paused game press any other key once again\n\n-> If you want to exit press esc. \n");
printf("\n\nPress any key to play game...");
if (getch() == 27)
exit(0);
}
void record() {
char plname[20], nplname[20], cha, c;
int i, j, px;
FILE* info;
info = fopen("record.txt", "a+");
getch();
system("cls");
printf("Enter your name\n");
scanf("%[^\n]", plname);
//************************
for (j = 0; plname[j] != '\0'; j++) { //to convert the first letter after space to capital
nplname[0] = toupper(plname[0]);
if (plname[j - 1] == ' ') {
nplname[j] = toupper(plname[j]);
nplname[j - 1] = plname[j - 1];
}
else nplname[j] = plname[j];
}
nplname[j] = '\0';
//*****************************
//sdfprintf(info,"\t\t\tPlayers List\n");
fprintf(info, "Player Name :%s\n", nplname);
//for date and time
time_t mytime;
mytime = time(NULL);
fprintf(info, "Played Date:%s", ctime(&mytime));
//**************************
fprintf(info, "Score:%d\n", px = Scoreonly());//call score to display score
//fprintf(info,"\nLevel:%d\n",10);//call level to display level
for (i = 0; i <= 50; i++)
fprintf(info, "%c", '_');
fprintf(info, "\n");
fclose(info);
printf("wanna see past records press 'y'\n");
cha = getch();
system("cls");
if (cha == 'y') {
info = fopen("record.txt", "r");
do {
putchar(c = getc(info));
} while (c != EOF);
}
fclose(info);
}
int Score()
{
int score;
GotoXY(20, 8);
score = length - 5;
printf("SCORE : %d", (length - 5));
score = length - 5;
GotoXY(50, 8);
printf("Life : %d", life);
return score;
}
int Scoreonly()
{
int score = Score();
system("cls");
return score;
}
void Up()
{
int i;
for (i = 0; i <= (bend[bend_no].y - head.y) && len < length; i++)
{
GotoXY(head.x, head.y + i);
{
if (len == 0)
printf("^");
else
printf("*");
}
body[len].x = head.x;
body[len].y = head.y + i;
len++;
}
Bend();
if (!kbhit())
head.y--;
}
I tried to find information on how to fix the code, but I did not succeed.

Connect four game, if statement

Here is code for my connect four game for exam. There are seven columns, if a number above 7 is entered it should say "Move not allowed", but if 0 is entered it should save the game.
When I enter 0 it says "Move not allowed". There is a code to save the game when 0 is entered but it says "Move not allowed" and doesn't go there. Can someone help?
#include <stdio.h>
#include <string.h>
typedef struct gameState{
int id;
char board[6][7];
int numberOfMoves;
char player1Name[20];
char player2Name[20];
}GameState;
void ShowMenu() {
printf("\n\n\n1. New Game \n");
printf("2. Load Game \n");
printf("3. Exit \n\n");
printf("Choose: ");
}
void ReadPlayerNames(char player1Name[20], char player2Name[20]) {
printf("\nName of first player:");
scanf("%s", player1Name);
printf("\nName of second player:");
scanf("%s", player2Name);
}
void PrintBoard(char board[6][7])
{
char header[] = " 1 2 3 4 5 6 7 ";
char border[] = "|---|---|---|---|---|---|---|";
printf("%s\n", header);
printf("%s\n", border);
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 7; j++)
{
printf("| %c ", board[i][j]);
}
printf("|\n");
printf("%s\n", border);
}
}
void ClearBoard(char board[6][7]) {
for (int i = 0; i < 6; i++){
for (int j = 0; j < 7; j++) {
board[i][j] = ' ';
}
}
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckDiagonals(char board[6][7], int i, int j, int goUpRight){
int connectedO = 0;
int connectedX = 0;
while(i >= 0){
if (board[i][j] != ' '){
if (board[i][j] == 'X'){
connectedX++;
connectedO = 0;
if (connectedX == 4){
if (goUpRight = 0){
board[i][j] = 'Y'; //checking if x won, putting Y on places of x
board[i + 1][j + 1] = 'Y';
board[i + 2][j + 2] = 'Y';
board[i + 3][j + 3] = 'Y';
} else {
board[i][j] = 'Y';
board[i + 1][j - 1] = 'Y';
board[i + 2][j - 2] = 'Y';
board[i + 3][j - 3] = 'Y';
}
return 1;
}
} else {
connectedO++;
connectedX = 0;
if (connectedO == 4){
if (goUpRight = 0){
board[i][j] = 'Y';
board[i + 1][j + 1] = 'Y'; //checking if o won, putting Y on places of o
board[i + 2][j + 2] = 'Y';
board[i + 3][j + 3] = 'Y';
} else {
board[i][j] = 'Y';
board[i + 1][j - 1] = 'Y';
board[i + 2][j - 2] = 'Y';
board[i + 3][j - 3] = 'Y';
}
return 2;
}
}
} else {
connectedO = 0;
connectedX = 0;
}
i--;
if (goUpRight == 1){
j++;
}else{
j--;
}
}
return 0;
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckRowsOrCols(char board[6][7], int rows){
int connectedO = 0;
int connectedX = 0;
int brI = 6;
int brJ = 7;
if (rows == 0){
brI = 7;
brJ = 6;
}
for (int i = 0; i < brI; i++){
for (int j = 0; j < brJ; j++) {
int pI = i, pJ = j;
if (rows == 0){
pI = j;
pJ = i;
}
if (board[pI][pJ] != ' '){
if (board[pI][pJ] == 'X'){
connectedX++;
connectedO = 0;
if (connectedX == 4){
if (rows == 0){
board[pI][pJ] = 'Y';
board[pI - 1][pJ] = 'Y';
board[pI - 2][pJ] = 'Y';
board[pI - 3][pJ] = 'Y';
} else {
board[pI][pJ] = 'Y';
board[pI][pJ - 1] = 'Y';
board[pI][pJ - 2] = 'Y';
board[pI][pJ - 3] = 'Y';
}
return 1;
}
} else {
connectedO++;
connectedX = 0;
if (connectedO == 4){
if (rows == 0){
board[pI][pJ] = 'Y';
board[pI - 1][pJ] = 'Y';
board[pI - 2][pJ] = 'Y';
board[pI - 3][pJ] = 'Y';
} else {
board[pI][pJ] = 'Y';
board[pI][pJ - 1] = 'Y';
board[pI][pJ - 2] = 'Y';
board[pI][pJ - 3] = 'Y';
}
return 2;
}
}
} else {
connectedO = 0;
connectedX = 0;
}
}
}
return 0;
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckForWinner(char board[6][7]) {
int rezultat = CheckRowsOrCols(board, 1);
if (rezultat != 0){
return rezultat;
}
rezultat = CheckRowsOrCols(board, 0);
if (rezultat != 0){
return rezultat;
}
for (int i = 0; i < 6; i++){
rezultat = CheckDiagonals(board, i, 0, 1);
if (rezultat != 0){
return rezultat;
}
}
for (int j = 0; j < 7; j++){
rezultat = CheckDiagonals(board, 5, j, 1);
if (rezultat != 0){
return rezultat;
}
rezultat = CheckDiagonals(board, 5, j, 0);
if (rezultat != 0){
return rezultat;
}
}
for (int i = 0; i < 6; i++){
rezultat = CheckDiagonals(board, i, 6, 0);
if (rezultat != 0){
return rezultat;
}
}
return 0;
}
void SaveGame(char board[6][7], int movesPlayed, char player1Name[20], char player2Name[20]){
printf("\n\n\nEnter ID for your game: ");
int id;
scanf("%d", &id);
GameState state;
state.id = id;
for (int i = 0; i < 6; i++){
for (int j = 0; j < 7; j++){
state.board[i][j] = board[i][j];
}
}
state.numberOfMoves = movesPlayed;
strcpy(state.player1Name, player1Name);
strcpy(state.player2Name, player2Name);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "ab");
if (filePointer == NULL){
printf("\nGames not found!");
return;
}
fwrite(&state, sizeof(state), 1, filePointer);
fclose(filePointer);
printf("\nGame with ID:%d saved!", id);
}
int MakeMove(char board[6][7], int movesPlayed, char player1Name[20], char player2Name[20]) {
char sign = 'X';
if (movesPlayed % 2 == 1){
sign = 'O';
}
int column;
while (1){
printf("\nChoose the column player %c(0 for save and exit): ", sign);
column;
scanf("%d", &column);
if (column >= 0 && column <= 7 && board[0][column-1] == ' '){
break;
}
printf("\nMove not allowed!\n");
}
if (column != 0){
for (int i = 6; i >= 0; i--) {
if (board[i][column-1] == ' ') {
board[i][column-1] = sign;
printf("\n\n\n");
break;
}
}
}else {
SaveGame(board, movesPlayed, player1Name, player2Name);
return 1;
}
return 0;
}
void PlayGame(char board[6][7], char player1Name[20], char player2Name[20], int movesPlayed){
while (1){
PrintBoard(board);
if (MakeMove(board, movesPlayed, player1Name, player2Name) == 1){
break;
}
movesPlayed++;
int result = CheckForWinner(board);
if (result != 0){
PrintBoard(board);
if (result == 1){
printf("\nX wins\n\n\n");
} else {
printf("\nO wins\n\n\n");
}
break;
}
if (movesPlayed == 42){
PrintBoard(board);
printf("\nTie!\n\n\n");
break;
}
}
}
void ListAllSavedGames(){
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
printf("\n%d, X: %s, O: %s, %d", state.id, state.player1Name, state.player2Name, (42 - state.numberOfMoves));
}
fclose(filePointer);
}
void ListAllPlayerGames(){
char playerName[20];
printf("\nName of player: ");
scanf("%s", playerName);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (strcmp(playerName, state.player1Name) == 0 || strcmp(playerName, state.player2Name) == 0){
printf("\n%d, X: %s, O: %s, %d", state.id, state.player1Name, state.player2Name, (42 - state.numberOfMoves));
}
}
fclose(filePointer);
}
int ShowTheBoard(){
int ID;
printf("\nEnter ID: ");
scanf("%d", &ID);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
int IDfound = 0;
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (ID == state.id){
IDfound = 1;
printf("\nX: %s, O: %s", state.player1Name, state.player2Name);
PrintBoard(state.board);
}
}
fclose(filePointer);
if (IDfound == 0){
return 1;
}
return 0;
}
int LoadAGame(){
int ID;
printf("\nEnter ID: ");
scanf("%d", &ID);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
int IDfound = 0;
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (ID == state.id){
IDfound = 1;
PlayGame(state.board, state.player1Name, state.player2Name, state.numberOfMoves);
}
}
fclose(filePointer);
if (IDfound == 0){
return 1;
}
return 0;
}
void ShowLoadMenu(){
int returnToMainMenu = 0;
while (returnToMainMenu == 0){
printf("\n\n\n1. List all saved games\n");
printf("2. List all saved games for a particular player\n");
printf("3. Show the board of one of the saved games\n");
printf("4. Load a game\n");
printf("5. Return to main menu\n");
printf("Choose: ");
int choice;
scanf("%d", &choice);
switch(choice){
case 1:
ListAllSavedGames();
break;
case 2:
ListAllPlayerGames();
break;
case 3:
while (ShowTheBoard() == 1){
printf("ID not valid!");
}
break;
case 4:
while (LoadAGame() == 1){
printf("ID not valid!");
}
returnToMainMenu = 1;
break;
case 5:
returnToMainMenu = 1;
break;
default:
printf("Wrong choice, try again!");
}
}
}
int main(){
int endOfProgram = 0;
while (endOfProgram == 0){
char board[6][7];
char player1Name[20];
char player2Name[20];
int movesPlayed = 0;
ShowMenu();
int choice;
scanf("%d", &choice);
switch(choice){
case 1:
ClearBoard(board);
ReadPlayerNames(player1Name, player2Name);
PlayGame(board, player1Name, player2Name, movesPlayed);
break;
case 2:
ShowLoadMenu();
break;
case 3:
printf("Goodbye!");
endOfProgram = 1;
break;
default:
printf("Wrong choice, try again!");
}
}
}
Culprit is likely to be inside MakeMove:
if (column >= 0 && column <= 7 && board[0][column-1] == ' ') {
break;
}
if you pass 0 as column, the first 2 tests will indeed succeed (both 0 >= 0 and 0 <= 7 are true). But third one tries to use board[0][-1]. -1 is not a valid index and you are invoking UB.
If column is 0, you should not test anything else, so your test should be:
if (column == 0 || (column > 0 && column <= 7
&& board[0][column-1] == ' ')) {
break;
}

C - Reading just one character with getchar()

I'm having some trouble with getchar(), in particular I have a char which, in a while loop, get the value returned from getchar() but I want to take just the first char and, if I insert a longer string (like "aaawssdawa"), I still want just the first char. My code, instead, processes the entire string.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#define ROWS 20
#define COLUMNS 65
char grid[ROWS][COLUMNS];
int score = 0;
void fillGridInitializer();
void printGrid();
void start();
void printScore();
void printAll();
int main(int argc, char *argv[]) {
start();
return 0;
}
void start() {
char movement;
int riga = 0, colonna = 0;
fillGridInitializer();
grid[riga][colonna] = '#';
system("clear");
printAll();
while (1) {
movement = getchar();
switch (movement) {
case 'w':
if ((riga - 1) >= 0) {
grid[riga][colonna] = '-';
riga = riga - 1;
}
break;
case 's':
if ((riga + 1) < ROWS) {
grid[riga][colonna] = '-';
riga = riga + 1;
}
break;
case 'a':
if ((colonna - 1) >= 0) {
grid[riga][colonna] = '-';
colonna = (colonna - 1) % COLUMNS;
}
break;
case 'd':
if ((colonna + 1) < COLUMNS) {
grid[riga][colonna] = '-';
colonna = (colonna + 1) % COLUMNS;
}
break;
default:
break;
}
if (movement == 'p') {
printf("+++++Game Over+++++\n\n");
break;
}
system("clear");
grid[riga][colonna] = '#';
printAll();
}
}
void printAll() {
printScore();
printGrid();
}
void fillGridInitializer() {
int i = 0, j = 0;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLUMNS; j++) {
grid[i][j] = '-';
}
}
}
void printScore() { printf("\t SCORE: %d\n", score); }
void printGrid() {
int i = 0, j = 0;
for (i = 0; i < ROWS; i++) {
printf("\t");
for (j = 0; j < COLUMNS; j++) {
printf("%c", grid[i][j]);
}
printf("\n");
}
}
After you process the first character, call getchar() in a loop until you get a newline or EOF.
Also, getchar() returns int, you should declare the variable accordingly, so you can compare with EOF properly.
void start() {
int movement;
int riga = 0, colonna = 0;
fillGridInitializer();
grid[riga][colonna] = '#';
system("clear");
printAll();
while (1) {
movement = getchar();
if (movement == EOF) {
break;
}
switch (movement) {
case 'w':
if ((riga - 1) >= 0) {
grid[riga][colonna] = '-';
riga = riga - 1;
}
break;
case 's':
if ((riga + 1) < ROWS) {
grid[riga][colonna] = '-';
riga = riga + 1;
}
break;
case 'a':
if ((colonna - 1) >= 0) {
grid[riga][colonna] = '-';
colonna = (colonna - 1) % COLUMNS;
}
break;
case 'd':
if ((colonna + 1) < COLUMNS) {
grid[riga][colonna] = '-';
colonna = (colonna + 1) % COLUMNS;
}
break;
default:
break;
}
if (movement == 'p') {
printf("+++++Game Over+++++\n\n");
break;
}
int ch;
while ((ch = getchar()) != '\n' && ch != EOF) {} # ignore the rest of the line
if (ch == EOF) {
break;
}
system("clear");
grid[riga][colonna] = '#';
printAll();
}
}
Assuming you just want to read a char and discard everything else in the same line, you can do the following:
Just read a line and only save the first char.
But, you shouldn't use this as it it vulnerable to buffer overflows(read what comes after it).
char read(){
char buf[BUF_SIZE];
gets(buf);
return buf[0];
}
But you shouldn't use gets because of possible buffer overflows.
In order to prevent that, you could use fgets(see this):
char read(){
char buf[BUF_SIZE];
fgets(buf,BUF_SIZE,stdin);
return buf[0];
}
In both cases, BUF_SIZE is a constant defining the maximum length of the string. The second example is buffer overflow protected but it will only work if the line ends before the buffer ends. You can just call fgets multiple times in order to bypass this issue:
char read(){
char buf[BUF_SIZE];
do{
fgets(buf, BUF_SIZE,stdin);
}while(buf[strlen(buf)]!='\n');
return buf[0];
}
Note that the last method needs <string.h>.
Integrated in your code, it would be something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define ROWS 20
#define COLUMNS 65
#define BUF_SIZE 255
char grid[ROWS][COLUMNS];
int score = 0;
void fillGridInitializer();
void printGrid();
void start();
void printScore();
void printAll();
int main(int argc, char *argv[]) {
start();
return 0;
}
void start() {
char movement;
int riga = 0, colonna = 0;
fillGridInitializer();
grid[riga][colonna] = '#';
system("clear");
printAll();
while (1) {
movement = read();
switch (movement) {
case 'w':
if ((riga - 1) >= 0) {
grid[riga][colonna] = '-';
riga = riga - 1;
}
break;
case 's':
if ((riga + 1) < ROWS) {
grid[riga][colonna] = '-';
riga = riga + 1;
}
break;
case 'a':
if ((colonna - 1) >= 0) {
grid[riga][colonna] = '-';
colonna = (colonna - 1) % COLUMNS;
}
break;
case 'd':
if ((colonna + 1) < COLUMNS) {
grid[riga][colonna] = '-';
colonna = (colonna + 1) % COLUMNS;
}
break;
default:
break;
}
if (movement == 'p') {
printf("+++++Game Over+++++\n\n");
break;
}
system("clear");
grid[riga][colonna] = '#';
printAll();
}
}
void printAll() {
printScore();
printGrid();
}
void fillGridInitializer() {
int i = 0, j = 0;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLUMNS; j++) {
grid[i][j] = '-';
}
}
}
void printScore() { printf("\t SCORE: %d\n", score); }
void printGrid() {
int i = 0, j = 0;
for (i = 0; i < ROWS; i++) {
printf("\t");
for (j = 0; j < COLUMNS; j++) {
printf("%c", grid[i][j]);
}
printf("\n");
}
}
char read(){
char buf[BUF_SIZE];
do{
fgets(buf, BUF_SIZE,stdin);
}while(buf[strlen(buf)]!='\n');
return buf[0];
}

Read second Line of File in C

So, I programmed a Cesar Encryption that saves the Position of "Space" Characters in the Second Line of the encryptet File with Numbers (like that:
HMEQSRHLMIV //Encryptet Text (here is Enter normally)
7 //Number where the Space Char is
)
My Problem now is, that when I read the String with fgets(), but it only reads until \n, so how do i get the second Line of the File?
here is my code if that helps.
#include <stdio.h>
#include <stdbool.h>
#define asize 80
void deleteEnter(char[]);
void decrypt(char[], int, char[]);
int main() {
char Message[asize] = {0};
int code = 0;
char encMessageFile[asize + 4] = {};
char encMessage[asize] = {};
char MessageFile[asize] = {};
FILE *fp;
FILE *fp2;
bool open = false;
printf("Gib die verschluesselte Datei an: \t");
fgets(encMessageFile,asize + 4, stdin);
deleteEnter(encMessageFile);
fp = fopen(encMessageFile, "r");
do {
if (fp == NULL) {
printf("\nEs wurde keine Datei gefunden die so heisst\n");
open = false;
fclose(fp);
} else {
open = true;
}
} while (open == false);
fgets(encMessage,asize,fp);
printf("\nGib den Code zum entschluesseln ein: \t");
scanf("%i", &code);
decrypt(encMessage, code, Message);
for (int i = 0; i < asize + 4; ++i) {
if (encMessageFile[i] == '.' && encMessageFile[i + 1] == 'e' && encMessageFile[i + 2] == 'n' && encMessageFile[i + 3] == 'c' && encMessageFile[i + 4] == '\0') {
for (int j = 0; j < i; j++) {
if (encMessageFile[j] != '\0') {
MessageFile[j] = encMessageFile[j];
MessageFile[j + 1] = '\0';
}
}
i = asize + 4;
}
}
fp2 = fopen(MessageFile, "w");
fputs(Message, fp2);
fclose(fp2);
fclose(fp);
remove(encMessageFile);
}
void deleteEnter(char encMessage[]){
for (int i = 0; i < asize; i++) {
if (encMessage[i] == '\0') {
i = asize;
} else if (encMessage[i] == '\n'){
encMessage[i] = '\0';
i = asize;
}
}
}
void decrypt(char encMessage[], int code, char Message[]) {
int a = code % 26;
int LeerPos[asize] = {0};
for (int k = 0; k < asize; k++) {
if (encMessage[k] == '\n'){
for (int i = 0; i < asize; ++i) {
if (encMessage[k + i] != '\0') {
LeerPos[i] = encMessage[k + i] - 80;
} else {
i = asize;
}
}
encMessage[k] = '\0';
}
}
for (int i = 0; i < asize; i++) {
if (encMessage[i] == '\0') {
i = asize;
} else {
for (int j = 0; j < a; j++) {
encMessage[i] = encMessage[i] - 1;
if (encMessage[i] < 'A' && encMessage[i] > 'A' - 2) {
encMessage[i] = 'Z';
}
}
}
}
int x = 0;
for (int l = 0; l < asize; l++) {
for (int i = 0; i < asize; i++) {
if (l == LeerPos[i]) {
Message[l] = ' ';
x++;
} else {
Message[l] = encMessage[l - x];
}
}
}
}
I expect, that the Program after the Decryption the Message is "DIAMOND HIER"
Because a User wantet that I post the Encryption too, here it is:
#include <stdio.h>
#include <stdbool.h>
#define asize 80
void cleanup (char[],char[], int[]);//2 arrays input und endinput
void deleteEnter(char[]);
void toupper(char[]); //endinput
int laenge(char[]); //input pointeranzleer
void encrypt(char[], int);
void Ausgabe(char[], char[], int[]);
//i abspeichern. for schleife in dritte array und array+1 und i++
int main() {
FILE *fp;
int schluessel=0;
char input[asize]={' '};
char endinput[asize]={' '};
char name[asize] = {' '};
bool open = false;
int LeerPos[80] = {0};
do {
printf("Bitte geben Sie den Namen der Datei ein:");
fgets(name, asize, stdin);
deleteEnter(name);
fp = fopen(name, "r");
if (fp == NULL) {
printf("\nEs wurde keine Datei gefunden die so heisst\n");
open = false;
fclose(fp);
} else {
open = true;
}
} while (open == false);
fgets(input, asize, fp);
printf("Bitte geben sie den Schluessel ein:");
scanf("%d",&schluessel);
cleanup(input,endinput, LeerPos);
toupper(endinput);
encrypt(endinput, schluessel);
Ausgabe(endinput, name, LeerPos);
fclose(fp);
return 0;
}
int laenge(char input[asize]){
int i=0;
while(input[i]!='\0'){
i++;
}
return i;
}
void cleanup(char input[asize],char endinput[asize], int LeerPos[]){
int j=0;
int LC = 0;
int lengthIn = laenge(input);
for(int i=0;i<lengthIn;i++){
if(input[i]!=' '){
endinput[j]=input[i];
j++;
} else {
LeerPos[LC] = i;
LC++;
}
}
}
void toupper(char endinput[asize]){
for(int i=0;i<laenge(endinput);i++){
if(endinput[i]>='a'&&endinput[i]<='z'){
endinput[i]=endinput[i]-('z'-'Z');
}
}
}
void encrypt(char S[asize], int code) {
int a = code % 26;
for (int i = 0; i < 80; i++) {
if (S[i] == '\0') {
i = 80;
} else {
for (int j = 0; j < a; j++) {
S[i] = S[i]+1;
if (S[i] == 'Z' + 1) {
S[i] = 'A';
}
}
}
}
}
void Ausgabe(char S[asize], char name[asize], int LeerPos[]) {
FILE *fpOut;
char EName[asize + 4];
char EncEnd[4] = {'.','e','n','c'};
for (int j = 0; j < asize; j++) {
EName[j] = name[j];
}
for (int k = 0; k < asize + 4; k++) {
if (EName[k] == '\0'){
for (int i = k; i < k + 4; ++i) {
EName[i] = EncEnd[i - k];
}
k = asize+4;
}
}
fpOut = fopen(EName, "w");
printf("\nVerschluesselte File: %s", EName);
for (int i = 0; i < asize; i++) {
if (S[i] == '\0') {
i = asize;
}else {
fprintf(fpOut, "%c", S[i]);
}
}
fprintf(fpOut, "%c", '\n');
for (int l = 0; l < asize; l++) {
if (LeerPos[l] != '\0'){
fprintf(fpOut, "%i", LeerPos[l]);
} else {
l = asize;
}
}
remove(name);
fclose(fpOut);
}
void deleteEnter(char S[]) {
for (int i = 0; i < asize ; i++) {
if (S[i] == '\0') {
i = asize;
} else if (S[i] == '\n') {
S[i] = '\0';
}
}
}
Thanks for all the Help.
Arigatou Gozaimasu

Resources