struktura do obslugi danych uzytkownikow

0

Pisze program w ktorym potrzebuje przechowac dane uzytkownikow. To znaczy nazwe, ip, oraz mac. Zastanawiam sie jaka bedzie najodpowiedzniejsza struktura. Czy wielowymiarowa tablica stringow bedzie dobra. Moze sa jakies inne struktory dzieki ktorym bede mogl przechowac te dane? Chodzi o to aby byla dynamicznie rozszerzalna

0

Dynamiczna tablica wlasnych struktur? A i powiedz pod ajkim względem najlepsza - najmniejsze zużycie pamięci, najłatwiejsza obsługa...

0

Głównie chodzi mi o łatwość obsługi. To znaczy gdy dodam nowego uzytkownika to zeby latwo bylo zrobic dla niego "miejsce w pamieci" oraz latwy odczyt i zapis poniewaz dane z tej tablicy beda przechowywane w pliku.

0

No chociażby tak...

#include <string>
#include <vector>
#include <stdint.h>

struct User {
    std::string user;
    uint8_t ip[4];
    uint8_t mac[6];
    };

typedef std::vector<User> UsersTable;

jak chcesz "łatwości obsługi" to IP oraz MAC rozpisz sobie jako unie, np tak:

union MAC  {
    uint8_t bytes[6];
    struct __attribute__((__packed__)) {
        uint32_t vendor:24;
        uint32_t device:24;
        };
    };

union IP {
    uint8_t bytes[4];
    uint32_t dword;
    };

struct User {
    std::string user;
    IP ip;
    MAC mac;
    };

jak nie używasz GCC, to rozwinięcia MAC nie użyjesz (pragma wygląda inaczej).
Zresztą, jak używasz czegoś do komunikacji sieciowej, to owo coś z pewnością udostępnia "swoje najswojsze" struktury do opisu MACów i IPków.

W zasadzie, dla ciebie najważniejszym "cudem" jest klasa vector...

0

Ranides mogl bys mi wytlumaczyc co sie dzieje w drugim sposobie ktory opisales bo nie bardzo to rozumiem. Acha mam pytanie jeszcze co to jest za zmienna uint32_t ktora jest wykorzytana w uni MAC czy to jest typ int bo mac przeciez ma rowniez znaki z alfabetu?

0

1' zlap jakis podrecznik i poczytaj o UNIACH, a sam sobie odpowiesz na pytanie pierwsze.
2' powinienes wiec raczej spytac: po co tak robic? - po to, aby mozna bylo latwo np. przeczytac numer IP zarowno jako 4 pojedyncze bajty, jak i jeden duzy long/dword
3' uint32_t to 32bitowy typ calkowity bez znaku. zakladajac ze uzywasz arch. 32bitowej, bedzie to to samo co unsigned long
4' zauwaz ze jedyne literki pojawiajace sie w MAC to ABCDEF i skojarz ze slowem 'hex'

0

Ja proponowałbym zastosowanie mapy (ew. multimapy) ze standardowej biblioteki STL

http://pl.wikibooks.org/wiki/C%2B%2B/Map

0

No ok Rudick, mapa fajna rzecz, propozycja jeszcze fajniejsza by była, jakbyś powiedział, co chcesz traktować jako klucz. W sumie i IP pasuje, i MAC, i name...

umówmy się, mapa super, tylko teraz czekamy na skoczo, który nam napisze, ze względu na co będzie tę listę przeszukiwał. Ewentualnie, można zawsze stworzyć jedną mapę na dane (sortowanie np po name), plus dwie mapy indeksujące po innych kluczach, które by zawierały pary:
MAC =>name
IP => name

;)

0
Ranides napisał(a)

No ok Rudick, mapa fajna rzecz, propozycja jeszcze fajniejsza by była, jakbyś powiedział, co chcesz traktować jako klucz. W sumie i IP pasuje, i MAC, i name...

umówmy się, mapa super, tylko teraz czekamy na skoczo, który nam napisze, ze względu na co będzie tę listę przeszukiwał. Ewentualnie, można zawsze stworzyć jedną mapę na dane (sortowanie np po name), plus dwie mapy indeksujące po innych kluczach, które by zawierały pary:
MAC =>name
IP => name

;)

z teorii baz danych, z tego co pamiętam to kluczem musi być wartość unikalna. Zarówno ip jak i mac pasują. Więc tu nie ma problemu

myślę że autor tematu trochę za mało informacji podał co to wykorzystania takiej struktury danych

0

Dla mnie najlepsze bylo by sortowanie po name poniewaz wlasnie po name wybiera sie u mnie uzytkownikow z listy i dopiero po wybraniu ma pojawiac sie reszta danych. Wiec jak to zrobic na mapach?
Domyslam sie ze cos w stylu

 map<string nazwa, string ip,string mac> uzytkownicy;

Tylko jak do tego dodac dane? Na Wikibooks jest dla mapy int,string a jak dla wiekszej?
Z gory dziekuje za odpowiedz.
Ps. Tak wyglada okno mojego programu
<image>
http://skoczo.republika.pl/zrzutekranu.png
</image>
Dane uzytkownika maja zapisac sie do struktury a nazwa ma byc widoczna z menu. Puzniej na podstawie nazwy mam pobrac reszte danych pozwolic na ich zmiane i zaktualizowac w strukturze

0

Jak już koniecznie chcesz to robić na mapach i STL to coś w tym stylu:

#include <iostream>
#include <utility>
#include <string>
#include <map>

using namespace std;

typedef pair<string, string> netAddr;
typedef map<string, netAddr> usersTable;

usersTable zuo;

int main() {
  zuo["zuy"] = netAddr("zue", "zuo");
  cout << zuo["zuy"].first + " " + zuo["zuy"].second << endl;
}

Ale raczej opowiedziałbym się za strukturą stringów o bardziej sensownych nazwach niż te stosowane w parach lub tą od Ranidesa, użycie prawie takie samo.

0

jeżeli sortowanie będzie tylko po name. to zrób coś takiego:

map<string, string> obiekt

i teraz tak, jako klucze podaj name.
A druga wartość to zrób coś takiego:

obiekt[name] = string_ip + string_mac

Będziesz mógł wtedy mieć posortowane po name. A przy wyświetlaniu pokaże Ci wszystkie dane.

Jak coś nie jasno napisałem to pisać ;)

0

Dzieki mysle ze twoj sposob deus powinien byc dobry. A da sie jakos ta mape wyswietlic w petli. To znaczy zeby wypisac wsztkie elementy ktore w niej sa. Cos jak z tablica w petli for?

0

@Rudick: napisałeś dokładnie to samo co ja z tą tylko różnicą, że nie ma jasnego rozgraniczenia pomiędzy IP i MAC...

Nawiązując do poprzedniego kodu:

  for (usersTable::iterator it = zuo.begin(); it != zuo.end(); it++)
    cout << it->first + " " + it->second.first + " " + it->second.second << endl;

Iterator po mapie zwraca referencję na pair<klucz, wartość>.

0

A ja to zasadziłbym sobie drzewo, gdzie jest napisane, że można mieć tylko jedną parę potomków?

0

Mam pewien problem z mapa. Uzywam nastepujacej mapy.

typedef pair<string, string> netAddr;
typedef map<string, netAddr> usersTable;

A problem pojawia sie w funkcji

void odczytaj_uz(usersTable *zuo)
{
	//usersTable zuo;
	ifstream plik;
	plik.open("uzytkownicy");
	char* nazwa;
	char* mac;
	char* ip;
	GtkListStore *store;
  	GtkTreeIter  iter;
  
	while(plik.eof())
	{
		plik>>nazwa;
		plik>>mac;
		plik>>ip;
		  	store = GTK_LIST_STORE(gtk_tree_view_get_model(
       	GTK_TREE_VIEW(list)));

  		gtk_list_store_append(store, &iter);
  		gtk_list_store_set(store, &iter, LIST_ITEM, nazwa, -1);
		zuo[nazwa] = netAddr(mac,ip);
	}
	
	plik.close();
	
}

Blad wyglada nastepujaco.
gtkclass.cpp:591: błąd: conversion from usersTable*, to non-scalar type usersTable, requested
wiem ze chodzi o to ze jest to wskaznik ale jak sobie poradzic z tym problemem? Prosze pomozcie.

0

Albo przyjmuj przez referencję (co jest najlepszym wyjściem) albo zrób dereferencję wskaźnika:

void odczytaj_uz(usersTable &zuo)

i reszta bez zmian albo:

(*zuo)[nazwa] = netAddr(mac,ip);
0

Działa dzięki.

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