0

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

Dharman
  • 30,962
  • 25
  • 85
  • 135
HerrYetii
  • 33
  • 6
  • 2
    don't think windows has [`usleep`](https://man7.org/linux/man-pages/man3/usleep.3.html) – yano Jan 04 '23 at 15:04
  • @Jabberwocky the includes are there, what's the equivalent of usleep in windows – HerrYetii Jan 04 '23 at 15:12
  • There is no `usleep` in Windows. Include `` and use `Sleep(200);` instead of `usleep(200000);` – Jabberwocky Jan 04 '23 at 15:15
  • `case 1: // Aus Datei laden char filename[20]; `As your error messages tell you, you cannot place a declaration at a label. Either use extra braces `{ }` around your `case` blocks or add an empty statement: `case 1: ; // Aus Datei laden char filename[20];` – Gerhardh Jan 04 '23 at 15:18
  • @Gerhardh his code compiles fine expect some minor warnings and the non existent `usleep` – Jabberwocky Jan 04 '23 at 15:20
  • @Jabberwocky that's interesting. Without including `windows.h` I get those error messages together with loads of other warnings. Including `windows.h` removes these errors. – Gerhardh Jan 04 '23 at 15:28
  • @Gerhardh it compile almost fine with gcc 11.1 : https://www.godbolt.org/z/f7h6aoY5d but not with oder gcc versions – Jabberwocky Jan 04 '23 at 15:29
  • 1
    @Jabberwocky OK, Looked again: The errors are still there in the list but it does not prevent MSVC from creating an executable. I find the output of MSVC rather confusing. (Normally I don't use MSVC) The diagnostics in "Output" window does not match the entries in "Error list" window. – Gerhardh Jan 04 '23 at 15:32

1 Answers1

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?.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Actually his code compiles fine with gcc 11.1+. Is this an extension? – Jabberwocky Jan 04 '23 at 15:28
  • @Jabberwocky Godbolt runs on Linux. Or did you mean the label issue? – Lundin Jan 04 '23 at 15:33
  • okay i have no more errors but now it stopps after asking me what percentage of living cells i want to have – HerrYetii Jan 04 '23 at 15:34
  • @Lundin yes, I meant the lable issue. – Jabberwocky Jan 04 '23 at 15:36
  • 2
    @Jabberwocky gcc generally seems to have tossed C compliance completely out the Window as per version 11. If you force it to be a conforming compiler `-std=c17 -pedantic-errors` then you get the expected error still. I guess someone was bored and invented yet another useless GNU C extension that nobody asked for... – Lundin Jan 04 '23 at 15:39
  • 2
    @Jabberwocky Oh, actually I just realized why. As per C23 you can place labels anywhere inside compound statements (committe report [N2508](https://www.open-std.org/jtc1/sc22/WG14/www/docs/n2508.pdf)). So this was a preparation for upcoming C23. Weird though, since gcc 11 is supposedly following C17 still. – Lundin Jan 04 '23 at 15:43
  • Similar change in the same patch was to turn `true`/`false` into `bool`. This change doesn't go live unless you use `-std=c2x` though. So I think the labels anywhere thing is almost certainly a little bug in gcc 11 and onward. – Lundin Jan 04 '23 at 15:52
  • @Lundin did you see my comment from earlier? now it stopps after asking me what percentage of living cells i want to have can you help me there or should i do another (new) question? – HerrYetii Jan 04 '23 at 16:08
  • @HerrYetii I don't know how your program is supposed to be used, ask the one who wrote it. – Lundin Jan 04 '23 at 16:47