Potrójny wskaźnik i tablica dynamicznie się powiększająca

0

Cześć, wykładowca wymaga ode mnie (1 rok), abym zastosował w moim projekcie potrójny wskaźnik oraz dynamicznie powiększaną tablicę, problem w tym, że mój program to przechowywacz haseł, czy password manager (po prostu dodajemy, usuwamy i wyświetlamy hasła, które potem są zapisywane do pliku txt). Nie mam zielonego pojęcia jak się do tego zabrać
Plik nagłówkowy Dane.h

#include <string>
using namespace std;


	class Dane {
	private:
		string strona;
		string login;
		string haslo;
	public:
		//przeciazenie
		Dane();
		Dane(string Strona, string Login, string Haslo);
		Dane(const Dane& pobranie);
		void zapis();
		void zapis(string Strona, string Login, string Haslo);
		void wyswietl();
		string get_strona();
		string get_login();
		string get_haslo();
	};

Dane.cpp

#include "pch.h"
#include <iostream>
#include "Dane.h"
#include <string>
using namespace std;


//zapis danych do pliku z klawiatury
void Dane::zapis() {
	cout << "Podaj strone: " << endl;
	cin >> Dane::strona;
	cout << "Podaj login: " << endl;
	cin >> Dane::login;
	cout << "Podaj haslo: " << endl;
	cin >> Dane::haslo;
}
//zapis danych do pliku z argumentów (np. jak juz jest cos w pliku, ze zmiennej)
void Dane::zapis(string Strona, string Login, string Haslo){
	this->strona = Strona;
	this->login = Login;
	this->haslo = Haslo;
}

Dane::Dane() {}
//lista inicjalizacyjna
Dane::Dane(string Strona, string Login, string Haslo): strona(Strona), login(Login), haslo(Haslo) { }

//konstruktor kopiujący
Dane::Dane(const Dane& pobranie) {
	this->zapis(pobranie.strona, pobranie.login, pobranie.haslo);
}

void Dane::wyswietl() {
	cout << Dane::strona << ": " << Dane::login << " " << Dane::haslo << endl;
}



// metody zwracajaca wartosci (wartosci sa  ogolnie prywatne, a przez to czesciowo staja sie publiczne), prywatne dla bezpieczenstwa
// nie modyfikuja wartosci, tylko wyswietlaja
string Dane::get_strona() {
	return Dane::strona;
}
string Dane::get_login() {
	return Dane::login;
}
string Dane::get_haslo() {
	return Dane::haslo;
}

oraz main

//Sejf Haseł
#include "pch.h"
#include <iostream>
#include <string>
#include <fstream>
#include "Dane.h"
using namespace std;

bool wczytywanie(string &strona,string &login,string &haslo,istream &file) {
	
	//wczytuje hasla (jesli juz jakies sa np)
			getline(file, strona);
			if (strona == "") return false;
			getline(file, login);
			getline(file, haslo);
			return true;
}
void add(Dane* hasla, int& ilosc_wpisow) {

	hasla[ilosc_wpisow].zapis();
	ilosc_wpisow++;
}
void view(Dane* hasla, int& ilosc_wpisow) {

	for (int j = 0; j < ilosc_wpisow; j++) {

		hasla[j].wyswietl();

	}
}
void save(Dane* hasla, int& ilosc_wpisow) {

	ofstream file;
	file.open("hasla.txt");
	for (int j = 0; j < ilosc_wpisow; j++) {
		//nie modyfikuja wartosci, tylko wyswietlaja
		file << hasla[j].get_strona() << endl << hasla[j].get_login() << endl << hasla[j].get_haslo() << endl;

	}

	file.close();
	delete[] hasla;
}
//dynamiczne rozszerzanie tablicy nie działa
/*void plustab(Dane* hasla, int& rozmiar) {

	Dane* tablica = new Dane[rozmiar + 1];
	for (int i = 0; i < rozmiar; i++) {

		tablica[i] = Dane(hasla[i]);
	}
	delete[] hasla;
	hasla = new Dane [++rozmiar];
	hasla = tablica;
	for (int i = 0; i < rozmiar; i++) {

		hasla[i] = Dane(tablica[i]);
		
	} 
	delete[] tablica;
}*/

int main() {
	// tworzenie tablicy obiektów na maks 20 haseł
	int rozmiar = 0;
	int i = 0;
	bool flag = true;
	Dane*** hasla = new Dane**[1];
	hasla[0] = new Dane* [1];
	hasla[0][0] = new Dane[20];
	ifstream file;
	file.open("hasla.txt");
	string strona;
	string login;
	string haslo;


	
	if (file.is_open()) {
		while (flag) {
			flag = wczytywanie(strona, login, haslo, file);
			if (flag) {
				//plustab(hasla, rozmiar);
				hasla[0][0][i].zapis(strona, login, haslo);
				i++;
			}
		}
	}
		file.close();
 
		//referencja
		int& ilosc_wpisow = i;
		char operacja;
		while (1) {
			cout << "Co chcesz zrobic?" << endl;
			cout << "a - dodac haslo " << endl;
			cout << "v - wyswietlic hasla " << endl;
			cout << "s - wyjsc i zapisac " << endl;
			cin >> operacja;

			switch (operacja) {
				//dodawanie haseł
			case 'a':
				
				add(**hasla,ilosc_wpisow);
				//plustab(hasla, rozmiar);
				break;

				//wyswietlanie hasel
			case 'v':
				view(**hasla, ilosc_wpisow);
				break;

				//zapis i zamkniecie
			case 's':
				save(**hasla, ilosc_wpisow);
				return 0;
			}
		}
}



w mainie mam zakomentowane dynamiczne rozszerzanie tablicy, lecz nie działa, może ktoś z tym także pomoże? Tak samo potrójny wskaźnik - został użyty, ale nie ma zastosowania, więc prowadzący się doczepił.
Dzięki z góry :)

5

Wrzuć treść zadania, bo z tego co przekazałeś potrójny wskaźnik nie ma żadnego sensu, poza byciem dla samego bycia. Za takie wymagania to wykładowca sam powinien oblać C++.

2

Lużny zestaw krytycznych uwag
(o potrójnym pointerze nie mówię, to jest uczywista patologia)

  • Konstruktory. jest ich trzy, to jeszcze nie jest ewidentnie za dużo, ale potrzebujesz tyle?
  • Konstruktor z metodą zapis() - konstruktor nie powinien wykonywać I/O i ogóle żadnej rzeczy która się może nie powieść. Szczególnie w C++ - w Javie i C# też jest to źle widziane, ale język zabezpiecza przed stworzeniem nieprawidłowego obiektu. W C++ jest to możliwe
  • nazwy są zakłamane, zapis nie robi zapisu itd
  • koszmarek. To Ci się kompiluje? Co chcesz uzyskać po prefiksie Dane:: ? Jak coś nie zmienia stanu obiektu, to nie sramy komentarza, tylko dajemy const
// metody zwracajaca wartosci (wartosci sa  ogolnie prywatne, a przez to czesciowo staja sie publiczne), prywatne dla bezpieczenstwa
// nie modyfikuja wartosci, tylko wyswietlaja
string Dane::get_strona() {
    return Dane::strona;
}
string Dane::get_login() {
    return Dane::login;
}
string Dane::get_haslo() {
    return Dane::haslo;
}
0
kq napisał(a):

Wrzuć treść zadania, bo z tego co przekazałeś potrójny wskaźnik nie ma żadnego sensu, poza byciem dla samego bycia. Za takie wymagania to wykładowca sam powinien oblać C++.

Właśnie ten potrójny wskaźnik nie ma żadnego zastosownia, myślałem, że to przejdzie, ale zirytował się na mnie, więc po prostu nie mam żadnego pomysłu jak mógłbym go zastosować.
screenshot-20200414132058.png

2

Poniżej masz przykład jak stworzyć/usunąć tablicę trzy wymiarową przy użyciu "potrójnego" wskaźnika. Zmiana rozmiaru tablicy może być zrealizowana przy użyciu tych funkcji.
Pamiętaj jednak, że praca z gołymi wskaźnikami jest podobna do żonglowania butelkami wypełnionymi nitrogliceryną. Wystarczy jeden najmniejszy błąd i .....

#include <iostream>

using namespace std;

template< typename T >
T*** allocate( int d1 , int d2 , int d3 )
{
    T*** table {nullptr};
    table = new T**[d1];
    for( int i=0 ; i<d1 ; ++i )
    {
        table[i] = new T*[d2];
        for( int j=0 ; j<d2 ; ++j )
        {
            table[i][j] = new T[d3];
        }
    }

    return table;
}

template< typename T >
void remove( T*** table , int d1 , int d2 )
{
    for( int i=0 ; i<d1 ; ++i )
    {
        for( int j=0 ; j<d2 ; ++j )
        {
            delete [] table[i][j];
        }
        delete [] table[i];
    }
    delete [] table;
}

int main(int argc, char *argv[])
{
  auto table = allocate<float>(10,20,30);
  // to do
  remove(table,10,20);
}
0
TomaszLiMoon napisał(a):

Poniżej masz przykład jak stworzyć/usunąć tablicę trzy wymiarową przy użyciu "potrójnego" wskaźnika. Zmiana rozmiaru tablicy może być zrealizowana przy użyciu tych funkcji.
Pamiętaj jednak, że praca z gołymi wskaźnikami jest podobna do żonglowania butelkami wypełnionymi nitrogliceryną. Wystarczy jeden najmniejszy błąd i .....

#include <iostream>

using namespace std;

template< typename T >
T*** allocate( int d1 , int d2 , int d3 )
{
    T*** table {nullptr};
    table = new T**[d1];
    for( int i=0 ; i<d1 ; ++i )
    {
        table[i] = new T*[d2];
        for( int j=0 ; j<d2 ; ++j )
        {
            table[i][j] = new T[d3];
        }
    }

    return table;
}

template< typename T >
void remove( T*** table , int d1 , int d2 )
{
    for( int i=0 ; i<d1 ; ++i )
    {
        for( int j=0 ; j<d2 ; ++j )
        {
            delete [] table[i][j];
        }
        delete [] table[i];
    }
    delete [] table;
}

int main(int argc, char *argv[])
{
  auto table = allocate<float>(10,20,30);
  // to do
  remove(table,10,20);
}

Cześć, dzięki za szybką odpowiedź. Mimo wszystko, nie wiem jak zastosować twój kod, ani jakie ma zastosowanie. No bo, co tak naprawdę daje mi tutaj tablica w trzech wymiarach?

1

Mimo wszystko, nie wiem jak zastosować twój kod, ani jakie ma zastosowanie.

Do tworzenia i usuwania tablicy trójwymiarowej tworzonej na stercie z wykorzystywaniem "potrójnych" wskaźników. Nawiasem mówiąc tworzenie tablic takiego przy pomocy "gołych" wskaźników jest
najłagodniej mówiąc nie zalecane. Ale to są studia, takie są wymogi prowadzącego i musisz się tego nauczyć.

Do zmiany rozmiaru tablicy. Tworzysz nową tablicę, kopiujesz elementy starej tablicy (to co można przekopiować) do nowej i następnie usuwasz starą.

Jeżeli chodzi o zastosowanie, to musisz sobie sam coś wymyślić. W zadaniu jest wymóg, żeby użyć tablicy dwu/trzy wymiarowej do przechowywania danych.
Czyli według mnie wystarczy tak definicja:

auto Password = allocate<Dane>( 20 , 20 , 20 );  // tablica 3D haseł

Teraz musisz tylko znaleźć pomysł jak taką tablicę wykorzystać w zadaniu.

0
Kaytec napisał(a):

Właśnie ten potrójny wskaźnik nie ma żadnego zastosownia, myślałem, że to przejdzie, ale zirytował się na mnie, więc po prostu nie mam żadnego pomysłu jak mógłbym go zastosować.
screenshot-20200414132058.png

Potrójny wskaźnik ma tutaj zastosowanie. Zwróć uwagę, że w założeniach stoi, że typem zwracanym we wszystkich funkcjach ma być void. Także w funkcji przydzielającej pamięć. Pytanie, jak zwrócić przydzieloną pamięć, gdy typem zwracanym funkcji ma być void? Ano można zapisać wskaźnik na przydzieloną pamięć pod adresem, przekazanym do funkcji w parametrze. I tutaj do gry wchodzi potrójny wskaźnik.

void allocRows(A*** pa, size_t rows) {
    *pa = new A*[rows];
}

A** a = nullptr;
A*** pa = &a;
allocRows(pa, 10);

Nazwa zmiennej "pa" sugeruje, że chodzi o wskaźnik na "a". Literaka "p" zapewne oznacza pointer.

2

Naprawdę proszę was: nie piszcie takiego kodu.
Używajcie smart pointerów i std::vector. https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete/
Dobry kod nie zawiera potrójnych wskaźników, a podwójne wskaźniki to tylko wtedy jeśli, coding convetion mówi, że wartości zwracane poprzez argument, powinny być przekazywane przez wskaźnik, np tak:

void convertToFoo(const std::string, std::shared_ptr<Foo> *p);

// użycie:
std::shared_ptr<Foo> p;
convertToFoo("Fofofofofofofo", &p);

To convertToFoo ustawia wartość wskaźnika za pomocą *p.

Tego zapamietywacza haseł można (i nawet trzeba) napisać bez użycia jakiegokolwiek wskaźnika, a co dopiero mówić o potrójnym wskaźniku. Trzeba się tylko wyzbyć mani pisania w stylu C (C nie ma smart pointerów, nie ma w standardzie struktur danych analogicznych do kontenerów STL).

0
MarekR22 napisał(a):

Naprawdę proszę was nie piszcie takiego kodu.
Używajcie smart pointerów i std::vector. https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete/
Dobry kod nie zawiera potrójnych wskaźników, a podwójne wskaźniki to tylko wtedy jeśli, coding convetion mówi, że wartości zwracane poprzez argument, powinny być przekazywane przez wskaźnik, np tak:

void convertToFoo(const std::string, std::shared_ptr<Foo> *p);

To convertToFoo ustawia wartość wskaźnika za pomocą *p.

Tego zapamietywacza haseł można (i nawet trzeba) napisać bez użycia jakiegokolwiek wskaźnika, a co dopiero mówić o potrójnym wskaźniku.

Wymóg to wymóg, ja nie mam na to wpływu. Mam ten projekt rozwijać przez cały semestr, kiedy jestem totalną nogą z programowania i kompletnie nie widzę jak mogę tu użyć potrójnego wskaźnika, tak, aby był użyteczny. Tablica tak jak w poleceniu miała być stworzona za pomocą new i delete, więc nic z tym nie mogę zrobić.

0

A zdradź może na jakim kursie masz takie zadanie?

PS
Na PW chętnie bym usłyszał co to za uczelnia ;)

1

W zasadzie potrójnych wskaźników się unika, chociażby poprzez zwykłe ich maskowanie:

typedef double Data;
typedef Data *ColData;
typedef ColData *RowData;
typedef RowData *CubeData;
// CubeData to faktycznie double***
0

Szczerze mówiąc nic mi nie dają wasze odpowiedzi, chociaż doceniam, to po prostu nic z tego nie rozumiem. Poziom mojego C++ leży, a nawet nie wiem jak którykolwiek z waszych kodów zaimplementować do swojego.

2

To może podejdźmy do tego inaczej i spróbujmy wspólnie dojść do rozwiązania "akceptowalnego" z punktów widzenia

  • Twojej znajomości C++
  • wymagań Twojego prowadzącego
  • współczesego C++

Zacznijmy od rzeczy podstawowej - jakie struktury danych sobie zaplanowałeś ?

BTW - widziałem sylabus tego kursu - to dość popularne podejście w stylu "nauczmy absolutnie wszystkiego na temat C/C++ w 30h".
Do tego dość często widziałem podejście prowadzących, którzy koniecznie chcieli aby w programie student zastosował absolutnie wszystkie omawiane techniki (to się potem bardzo łatwo ocenia - punkcik za każdy zdefiniowany konstruktor, punkcik za każde zagnieżdzenie wskaźnika itd...)
Przypuszczam, że stąd te delikatnie mówiąc "nieoptymalne" pomysły ze wskaźnikami i przewiduję, że za chwileczkę będziemy mieli pytania o konstruktor kopiujący, dziedziczenie wirtualne i przeciążanie operatora dodawania dla haseł ;)

0
Bartłomiej Golenko napisał(a):

To może podejdźmy do tego inaczej i spróbujmy wspólnie dojść do rozwiązania "akceptowalnego" z punktów widzenia

  • Twojej znajomości C++
  • wymagań Twojego prowadzącego
  • współczesego C++

Zacznijmy od rzeczy podstawowej - jakie struktury danych sobie zaplanowałeś ?

BTW - widziałem sylabus tego kursu - to dość popularne podejście w stylu "nauczmy absolutnie wszystkiego na temat C/C++ w 30h".
Do tego dość często widziałem podejście prowadzących, którzy koniecznie chcieli aby w programie student zastosował absolutnie wszystkie omawiane techniki (to się potem bardzo łatwo ocenia - punkcik za każdy zdefiniowany konstruktor, punkcik za każde zagnieżdzenie wskaźnika itd...)
Przypuszczam, że stąd te delikatnie mówiąc "nieoptymalne" pomysły ze wskaźnikami i przewiduję, że za chwileczkę będziemy mieli pytania o konstruktor kopiujący, dziedziczenie wirtualne i przeciążanie operatora dodawania dla haseł ;)

Nie mam zaplanowanych struktur danych, właściwie to nie wiem nawet konkretnie o co Ci chodzi, znam samo pojęcie, ale nie wiem jak ono się ma do tematu. Także trafiłeś w sedno, na następne zajęcia muszę mieć też konstruktor kopiujący, delegujący i domyślny, i destruktor, agregacje, zagnieżdżenie klas, mechanizm przyjaźni i specyfikacja deklaracji auto.

0

Co to jest specyfikacja deklaracji auto?

0

screenshot-20200416202227.png

0
Kaytec napisał(a):

Nie mam zaplanowanych struktur danych, właściwie to nie wiem nawet konkretnie o co Ci chodzi, znam samo pojęcie, ale nie wiem jak ono się ma do tematu.

Zapomnij na chwilę o tych konkretnych wymaganiach technicznych na drugie czy trzecie zajęcia.

Masz pomysł na program - wiesz co chcesz napisać. To już bardzo dużo. Skoro masz problem z okresleniem w tej chwili struktur danych, to może inaczej - opisz przykładowe scenariusze użycia Twojego programu. Ale szczegółowo, nie na poziomie "A to taki program do trzymania haseł".

0
Bartłomiej Golenko napisał(a):
Kaytec napisał(a):

Nie mam zaplanowanych struktur danych, właściwie to nie wiem nawet konkretnie o co Ci chodzi, znam samo pojęcie, ale nie wiem jak ono się ma do tematu.

Zapomnij na chwilę o tych konkretnych wymaganiach technicznych na drugie czy trzecie zajęcia.

Masz pomysł na program - wiesz co chcesz napisać. To już bardzo dużo. Skoro masz problem z okresleniem w tej chwili struktur danych, to może inaczej - opisz przykładowe scenariusze użycia Twojego programu. Ale szczegółowo, nie na poziomie "A to taki program do trzymania haseł".

Tematem programu jest sejf haseł. Użytkownik dopisuje hasła do programu i potem może je wywołać celem trzymania ich w jednym miejscu, aby nie musieć ich zapamiętywać. Idealnym odbiorcą takiego programu jest chociażby moja mama - nie pamięta swoich haseł, nie zapisuje ich, a jak już je zapisze, to często zgubi albo usunie dane z przeglądarki (whatever, wymyślam). W przyszłości myślałem o tym, żeby użytkownik włączając aplikację musi się do niej zalogować podając hasło (wszystko oczywiście zapisywałoby się lokalnie, ale w jakiś sposób encrypted).

Mam nadzieję, że o to Ci chodziło.

1

Więc tak, logowanie się wyglądałoby w ten sposób:
Do samego programu po prostu będzie przypisane hasło (bez dodatkowych użytkowników), użytkownik miałby nieograniczoną ilość prób logowania w jakimś while'u, sprawdzane byłoby if'em, więc byłoby bezpośrednio w kodzie (nie chodzi tu o bezpieczeństwo, a praktyczność i prostotę, bo podejrzewam, że nic lepszego i tak bym nie był w stanie zrobić).

Dodatkowo, trafiłem dzisiaj na pluralsighta i oglądam serię Kate Gregory i trafiłem właśnie na wektory o których ktoś wcześniej mówił, niestety wprowadziła je na bardzo podstawowym poziomie, a chciałem je zaimplementować do dynamicznej tablicy, ale nie znam się na nich w ogóle, więc poszukuje jakiegoś źródła/przykładu z którego mógłbym się czegoś nauczyć. Nie za bardzo wiem jak mógłbym połączyć swoją klasę Dane z wektorem, żeby wypisał Dane wprowadzone przez użytkownika oraz żeby był w stanie zapisywać.

1

Mam lepszą propozycje, pójdź do tego wykładowcy, niech Ci pokaże realne zastosowanie triple-pointerów, wykorzystywane w profesjonalnym (a nie śmiesznym) oprogramowaniu. (aha, i sprecyzuj, że to ma być profesjonalne, a nie śmieszne oprogramowanie) I niech oceni prawdopodobieństwo że będziesz akurat to robił jako programista w swojej pracy. Zapytaj też go, czy nie jest to aby anty-wzorzec w tym wymuszonym "kontekście".

2
Codedemens napisał(a):

Mam lepszą propozycje ...

Jedzie kowboj po prerii i nagle zostaje otoczony przez indian.
- No to już po mnie. Pomyślał.
I tu słyszy w głowie głos: - Jeszcze nie! Podejdź do wodza i pluń mu w twarz!
Podszedł, plunął.
A głos w głowie: - Dopiero teraz, po tobie.

@Codedemens, to ty byłeś tym głosem?

0
_13th_Dragon napisał(a):
Codedemens napisał(a):

Mam lepszą propozycje ...

Jedzie kowboj po prerii i nagle zostaje otoczony przez indian.
- No to już po mnie. Pomyślał.
I tu słyszy w głowie głos: - Jeszcze nie! Podejdź do wodza i pluń mu w twarz!
Podszedł, plunął.
A głos w głowie: - Dopiero teraz, po tobie.

@Codedemens, to ty byłeś tym głosem?

Sigma Male never dies, Comrade General.

3

Pominę na razie moją opinię o trolowaniu i "buractwie" i spróbuję jeszcze raz...

@Kaytec - Twoim "zadaniem" było przygotowanie szczegółowej specyfikacji tego jak program ma działać z punktu widzenia użytkownika i ewentualni wymogów "formalnych". Zamiast tego po trzech dniach pojawiło sie jedno zdanie w którym pomieszałeś wymagania z instrukcjami jak je zaimplementować... Może nie do końca zrozumiałeś o co mi chodziło - więc spróbujmy inaczej.

  1. Wyobraź sobie, że masz worek dolarów. Duży.
  2. Nie masz pojęcia jak zrobić to zadanie, więc postanawiasz je zlecić.
  3. Na świecie jest tylko jeden programista który może to zrobić - na szczęście jest to "idealny" programista, który za pierwszym razem dostarczy Ci bezbłędny program napisany idealnie zgodnie z Twoją specyfikacją
  4. Problem polega na tym, że za swoje usługi programista żąda całego worka dolarów

Masz tylko jedną szansę na opisanie funkcjonalności programu. Dostaniesz dokładnie to co opisałeś, bez żadnego zgadywania co miałeś na myśli. Ponieważ programista jest idealny i dostarcza Ci dokładnie to co zamówiłeś - nie ma szans na żadne poprawki ani reklamacje.
Jak sądzisz - czy na podstawie tego co do tej pory opisałeś jest szansa, że dostaniesz sensowny program ?

Ten scenariusz jest oczywiście nierealny w praktyce. Nie ma ani idealnych programistów ani perfekcyjnej specyfikacji wymagań.
Dlaczego zatem w ogóle o tym piszę? Bo bez opisu co dokładnie chcesz osiągnąć nie będziemy w stanie Ci pomóc. Podekreślam - co a nie jak - wybacz nasze "buractwo", ale my najprawdopodobniej lepiej od Ciebie wiemy jak to zrobić. Twoja jedyna "przewaga" polega na tym, że masz jakąś wizję efektu końcowego.

Jeśli będziemy dokładnie wiedzielu co chcesz zrobić, to być może pojawi się pomysł gdzie w takim projekcie wpleść potrójny wskaźnik, tak żeby to miało choćby śladowy sens.

Jak na razie - z mojego punktu widzenia dostałeś w tym wątku dwie dobre odpowiedzi (od @TomaszLiMoon i @Pebal). W obu przypadkach - problemem jest znalezienie sensownego zastosowania dla tego typu kodu w Twoim projekcie.

4

Uprzedzam że absolutnie nigdy nie należy tego robić w ten sposób (ponieważ jest totalnie bez sensu), ale:

#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;

void append(char ***tb,size_t *count,const char *str)
{
   size_t index=(*count)++;
   *tb=(char**)realloc(*tb,*count*sizeof(char*));
   size_t size=strlen(str)+1;
   char *copy=(char*)malloc(size);
   memcpy(copy,str,size);
   (*tb)[index]=copy;
}

void print(char **tb,size_t count) { while(count--) cout<<*(tb++)<<endl; }

int main()
{
   char **tb=0;
   size_t count=0;
   append(&tb,&count,"Ala");
   append(&tb,&count,"ma");
   append(&tb,&count,"kota");
   print(tb,count);
   return 0;
}
1

@MarekR22:

Uniwersalne, bez znaczenia czy wykładowca, czy współpracownik, czy komandos.

1

Wow gwiazdeczki hurey XD.
Czy mój program spełnia wymogi wykładu przerób na C++ powiedz, że zaimplemnetowałeś algorytm half Triangel piramide printer XD.
Propozycja 1: hasło w 3d wpakuj i zapisz jako binarke jako prostą funkcje do hash haseł ;p, tylko jakoś magicznie np. że pierwsza linia będzie miała indexy odczytu hasła, a ostatnia hasło tak przestawione.
Propozycja 2: zaimplementuj liste i tam wpakuj tablice 3d ;p, co program robi przechowuje *** gwiazdeczki XD, nie wiem czy tylko to przejdzie hehe.

https://4programmers.net/Forum/1672187
https://code.sololearn.com/cjt2HFLwPvu2/#c

0

@Kaytec
Podaj całą treść zadania, podaj etap 1 (bo nawet jeżeli coś napisałeś, to primo: Nie wiemy czy jest to zgodne z etapem 1, secundo: nie wiemy w ogóle jak ma się etap 1 do etapów 2 i 3)
I jeżeli są etapy po 3, podaj je również. Podaj w jednym poście wszystko co jest wymagane do tego zadania. Bo aktualnie, to my musimy rozszyfrowywać puzle.
Proponuję też, że jeżeli jest to triple raw-pointer, dorzucić do tego rozwiązania zadania jakiegoś rodzaju test, aby sprawdzić, czy na pewno alokacja przebiegła prawidłowo. Nie trzeba tego testu dawać dla mocodawcy, bo ten test jest tylko po to, aby sprawdzić, czy na pewno zadanie jest rozwiązane prawidłowo.
Oprócz treści zadania podaj też kontekst wszystkiego co jest związane z tymi etapami. Etap 3 odgórnie narzuca mechanizmy które wszyscy znamy, ale nie wiemy w jakich konktekstach (Bo napisane jest - w odpowiednich kontekstach na czerwono)

Wykonanie tego zadania (z wyłączeniem metod brute-force) jest niewykonalne w obecnej formie.

Edit:

Proponuję abyś zapisał to w formie:

[zwięzły opis tego co musisz zrobić, na poziomie czysto teoretycznym/abstrakcyjnym]

[ETAP 1 - zdjęcie]
[ETAP 2 - zdjęcie]
[ETAP 3 - zdjęcie]
[Inne etapy jeżeli są]

[Opis zadania / Twoja narracja na temat tego co wykładowca mówił na temat tego zadania.]

[Sformatowany kod źródłowy tego co udało Ci się stworzyć]

[Inne informacje - jaką masz spontaniczność/poziom wolności do użycia swoich własnych rzeczy/pomysłów do tego projektu; jakie są konteksty podane w etapie 3 (czy ich nie ma? czy musisz sam je dopasować odpowiednio); co odgórnie musisz zrobić]


Jeżeli ktoś ma pomysł na lepszą formę, niech napisze własnego posta, albo do mnie na PW / napisze komentarz to zedytuję tego posta.

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