Projekt / tablice dwuwymiarowe/łańcuchy znakowe

0

Witam wszystkich!
Jest to mój pierwszy wpis na tym forum.
Moim zadaniem jest utworzenie tablicy dwuwymiarowej zawierającej dane studentów np. imię, nazwisko, numer indeksu i dalsza praca z tą tablicą. Już dość długi czas męczę się, żeby jakkolwiek zaimplementować taką tablicę i wyświetlić ją na ekranie konsoli w postaci kolumn i wierszy.
Czy ktoś byłby w stanie nakierować mnie jak taki twór ma powstać?
Z góry dziękuję za wszystkie odpowiedzi! Pozdrawiam

0

screenshot-20190529173257.png
To jest program, który wypisuje mi po prostu liczby w postaci takiej tablicy i mogę odczytać wartość z konkretnej komórki. Chciałbym zrobić to samo na napisach.

0

Edytowałem. Powinno być ok.

Tak naprawdę, to chciałbym się przede wszystkim dowiedzieć jak zaimplementować wyrazy w tablicy, żebym później mógł je wyświetlić w postaci %s, a nie jako pojedyncze litery(%c).

1
HypheN napisał(a):

Edytowałem. Powinno być ok.

No nie bardzo. Miałeś kod wrzucić jako tekst, a nie obrazki.

Tak naprawdę, to chciałbym się przede wszystkim dowiedzieć jak zaimplementować wyrazy w tablicy, żebym później mógł je wyświetlić w postaci %s, a nie jako pojedyncze litery(%c).

Jeśli tablica znaków posiada znak '\0' to można ją wypisać poprzez %s:

#include <stdio.h>
#include <string.h>

int main()
{
    char str[10];
    str[0] = 'a';
    str[1] = 'l';
    str[2] = 'a';
    str[3] = '\0';

    printf("%s, %lu\n", str, strlen(str));

    return 0;
}
0

Okej. Rozumiem, a jak to zapisać w tablicy dwuwymiarowej? W sensie chciałbym żeby:

#include <stdio.h>
#include <string.h>
int main()
{
char str[10][10];
str[0][0] = "napis";
printf("%s, %lu\n", str, strlen(str));

    return 0;
}

Taki zapis nie przechodzi, ale chciałem pokazać o co mi chodzi.

0
#include <stdio.h>
#include <string.h>

int main()
{
    char str[10][10];
    str[0][0] = 'a';
    str[0][1] = 'l';
    str[0][2] = 'a';
    str[0][3] = '\0';
    printf("%s, %lu\n", str[0], strlen(str[0]));
    
    strncpy(str[1], "ma kota i konia i psa i dziadka", 9);
    printf("%s, %lu\n", str[1], strlen(str[1]));

    return 0;
}
1

Nie wiem dlaczego nikt nie zapytał...
Te dwuwymiarowe tablice chcesz bo musisz (ktoś Ci kazał tak zrobić) czy po prostu nie masz innego pomysłu ?

struct Student {
  char imie[10];
  char nazwisko[10];
  int indeks;
};

int main()
{
  struct Student tab[10];
...
}
0

Muszę, w poleceniu mam zapisane, aby za pomocą tablic dwuwymiarowych stworzyć bazę studentów.

0

Stwórz tablicę dwuwymiarową składającą się z kilku rekordów mieszczącą w sobie dane dotyczące studentów(imię, nazwisko, rocznik..)
1.Pozwól użytkownikowi wybrać jeden dowolny element tablicy(wybór wiersza i kolumny) i wyświetlić go w terminalu
2.Zapisz tablicę do pliku tekstowego.
3.Odczytaj zapisany plik tekstowy i wyświetl zawartość tablicy w terminalu.

0

Masz wykorzystać tablice dwuwymiarowe do czegoś takiego? A jaka jest definicja tablicy jako struktury danych? Tablica przechowuje dane ale TEGO SAMEGO TYPU. Więc jeśli masz imię i nazwisko jako C-łańcuchy ale index jako pole np. int to w jakiej chcesz to tablicy zachować?.
To znaczy żeby było jasne. Da się to zrobić ale jako że przechowujesz różne dane musiałbyś mieć coś takiego: void*** studenci;.
studenci = malloc(ile * (void**)); ile odczytasz za pomocą scanf. Chyba, że będziesz używać co chwilę realloc (wersja bardziej hardcore'owa) :P
Później w pętli:
studenci[i] = malloc(3 * sizeof(void*)); bo masz 3 pola: imie, nazwisko i index.
Później odczytujesz imie, nazwisko i dajesz je do jakiegoś większego bufora by sprawdzić ile znaków zajmują. Oraz odczytujesz wartość index. I dajesz.
studenci[i][0] = malloc(strlen(buffer.imie) + 1);
strcpy(studenci[i][0], buffer.imie); strcpy automatycznie przekopiuje znak \0 z bufora.
index jako że jest typu int przekopiujesz za pomocą memcpy.
Nie wiem czy o to chodziło temu który zlecił Ci to zadanie. Do tego wystarczy jednowymiarowa tablica struktur. Kod poniżej.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct student {
    char imie[20];
    char nazwisko[30];
    int index;
} buffer;

int main() {
    void*** studenci;
    int ile;

    printf("Ile studentow: ");
    scanf("%d", &ile);
    studenci = malloc(ile * sizeof(void**));

    for(int i=0; i<ile; i++) {
        printf("Imie: ");
        scanf("%s", &buffer.imie);
        printf("Nazwisko: ");
        scanf("%s", &buffer.nazwisko);
        printf("Index: ");
        scanf("%d", &buffer.index);

        studenci[i] = malloc(3 * sizeof(void*));

        int imieLen = strlen(buffer.imie) + 1;
        int nazwiskoLen = strlen(buffer.nazwisko) + 1;

        studenci[i][0] = malloc(imieLen);
        studenci[i][1] = malloc(nazwiskoLen);
        studenci[i][2] = malloc(sizeof(int));

        strcpy(studenci[i][0], buffer.imie);
        strcpy(studenci[i][1], buffer.nazwisko);
        memcpy(studenci[i][2], &buffer.index, sizeof(int));
    }

    for(int i=0; i<ile; i++) {
        /* wypisze: 0: [Jan, Kowalski, 50] */
        printf("%d: [%s, %s, %d]\n", i, (char*)studenci[i][0], (char*)studenci[i][1], *(int*)studenci[i][2]);
    }

Aha to nie jest cały kod. Nie zapomnij zwolnić pamięci :P
Jedynie czego uczy to zadanie to posługiwanie się wskaźnikami do void.

0

Paskudztwo... No to coś w tym stylu...

#define WIERSZE 10
#define KOLUMNY 3
#define IMIE 0
#define NAZWISKO 1
#define INDEKS 2
...

char * tab[WIERSZE][KOLUMNY];

// poniższe dla indeksów 0,1,2,...,WIERSZE-1
tab[0][IMIE] = (char*)malloc(10);
tab[0][NAZWISKO] = (char*)malloc(10);
tab[0][INDEKS] = (char*)malloc(10);

strncpy(tab[0][IMIE], "Jan", 10);
strncpy(tab[0][NAZWISKO], "Kowalski", 10);
strncpy(tab[0][INDEKS], "11111", 10);

...

// zapytaj o wiersz i kolumne
scanf(...)
...

// wypisz komórkę (punkt 1)
printf("%10s", tab[wiersz][kolumna]);

Z ciekawości - co to za szkoła/uczelnia ?

0

W zasadzie potrzebujesz tablicy 3 wymiarowej, gdzie wewnętrzny wymiary to łańcuch znakowy. Masz dwie opcje - ciąg znakowy ma ograniczoną długość albo jest zmiennej długości.
W pierwszym przypadkupadku musisz przy zapisie sprawdzać czy nie próbujesz zapisać za dużo i wyświetlić błąd albo po cichu uciąć łańcuch. Funkcje, które będą pomocne to strncpy, ewentualnie strlen.
W drugim przypadku musisz wiedzieć kiedy przeprowadzić realokacje. Na pałe można to robić za każdym razem przy pomocy realloc.

W obu przypadkach czytanie z konsoli należy ograniczyć, by nie doszło do overflow. Można czytać do jakiegoś dużego buforu tymczasowego. Albo zaimplementować własny scanner, który czyta w kawałkach, a potem składa string.

Inna kwestią jest serializacja do i z pliku. Ale może najpierw uporają się z 1 problemem.

0

Politechnika Wrocławska

0

Można na przykład tak.

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 * dst - has to be NULL or pointer to dynamically allocated memory
 *       holding valid null terminated c-string.
 * result - pointer to line that was read. rememebr to free if no longer used.
 */
char* readline(char *dst)
{
    const size_t alloc_grow = 128;
    size_t size = 0;
    size_t end = 0;

    // read line
    while (true) {
        size += alloc_grow;
        dst = realloc(dst, size);
        if (!dst) {
            end = 0;
            break;
        }

        fgets(dst + end, size - end, stdin);
        end += strlen(dst + end);
        
        if (feof(stdin) || dst[end - 1] == '\n') {
            break;
        }
    }

    // strip \n or \r\n
    if (end >= 1 && dst[end - 1] == '\n') {
        dst[end - 1] = '\0';
        if (end >= 2 && dst[end - 2] == '\r') {
            dst[end - 2] = '\0';
        }
    }

    return dst;
}

#define ROW_COUNT 10
#define COL_COUNT 3

typedef char* table_t[ROW_COUNT][COL_COUNT];

void dump_table(table_t table) 
{
    printf("Table dump, values truncated to 20 chars:\n");
    for (size_t i = 0; i < ROW_COUNT; i++) {
        for (size_t j = 0; j < COL_COUNT; j++) {
            char *val = table[i][j];
            if (!val) {
                printf("%20.20s,", "NULL");
            } else {
                printf("%20.20s,", table[i][j]);
            }
        }
        putc('\n', stdout);
    }
}


int main()
{
    table_t table = {0};
    dump_table(table);

    printf("provide value for table[0][0] >\n");
    table[0][0] = readline(table[0][0]);

    putc('\n', stdout);
    dump_table(table);

    // ignore memory free, exiting anyway

    return 0;
}

Polecam zapoznać się z tym, co zostało napisane w wątku i stworzenie własnego rozwiązania.

1 użytkowników online, w tym zalogowanych: 0, gości: 1