Przeiterowanie po liście jednokierunkowej

Przeiterowanie po liście jednokierunkowej
Hodor
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Warszawa
  • Postów: 337
0

Utworzyłem listę jednokierunkową:

Kopiuj
struct Node {
    Node *next;
    std::string data;
}

Następnie włożyłem do środka dane.
Po tym jak już mam listę gotową tzn. wypełnioną danymi, chcę utworzyć plik .txt o nazwie data.txt dla każdego elementu owej listy. (nie chcę tworzyć plików od razu przy wkładaniu do listy!)

Muszę więc po prostu przeiterować po tej liście, ale coś mi to nie wychodzi.

Kopiuj
void CreateFiles(Node *&head)
{
    std::string filename;
    while (aktualny pointer pointuje na next element) {
        // tworzymy plik
        filename = head->data;
        std::ofstream resultfile(filename+".txt");
        // przypisanie pointera na nastepny element listy
        head = head->next;
    }
}

int main()
{
     Node *pointerek = nullptr;
     CreateFiles(pointerek);
}

Celowo wpisałem pseudokod w warunku while, bo czuję że tam mam błąd. Próbowałem:

Kopiuj
while (head->next != nullptr)

jak i innych różnych dziwnych kombinacji. Pomoże ktoś?

YooSy
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 472
1

while (head->next != nullptr) dlaczego pętla ma zakończyć przed obsłużeniem ostatniego poprawnego elementu?
Skoro w pętli przechodzisz wskaźnikiem na następny element, head = head->next; to wystarczy w
warunku pętli while(head). Poza tym head powinien być jeden, a ten iterator może być po prostu it, tmp, etc.

edit:
https://www.p-programowanie.pl/cpp/lista-jednokierunkowa-c/

Hodor
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Warszawa
  • Postów: 337
0

@YooSy: Próbuję też tak:

Kopiuj
void createfiles(Node *&head)
{
    Node *p = head;
    std::string nazwa;
    std::cout << "to się wykona";
    while (p) {
        std::cout << "to sie nie wykona";
        nazwa = p->instructor;
        std::ofstream outfile (nazwa+".txt");
        p = p->next;
    }
}

int main()
{
     Node *pointerek = nullptr;
     CreateFiles(pointerek);
     std::cout << "a to tez sie wykona";
}
lion137
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5025
2
Kopiuj
void do_sth(node * head){
	node * tmp = head;
	while(tmp) {
		/* Do sth with tmp */
		tmp = tmp->next;
	}
}
// main:
do_sth(list_head);
YooSy
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 472
2
Kopiuj
while (p) {
        std::cout << "to sie nie wykona";
        nazwa = p->instructor;
        std::ofstream outfile (nazwa+".txt");
        p = p->next;
    }

Czyli to co przekazujesz jest nullptr, więc p również.
A to dlatego

Kopiuj
Node *pointerek = nullptr;
     CreateFiles(pointerek); 

Do przeiterowania nie ma potrzeby przekazywać wskaźnika przez referencję.

Hodor
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Warszawa
  • Postów: 337
0

Prawdopodobnie problem jest po mojej stronie gdzieś, bo w rzeczywistości kod jest trochę bardziej złożony. Gdy próbowałem teraz na jakimś prostszym prototypie to zrobić, to działało dobrze.

tajny_agent
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1340
0

Skoro to C++ to użyj std::forward_list i nie trać czasu na wymyślanie koła na nowo ;)

lion137
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5025
2
Kopiuj
void f(int  a) {
	a += 1;
}

void f2(int * a) {
	*a += 1;
}


int main() {
	
	int a = 41;
	f(a);
	cout << a << endl;
	int * ptr = &a;
	f2(ptr); // lub f2(&a);
	cout << a <<endl;
	return 0;
}

W przypadku funkcji f, Wysyłasz a przez wartość, tworzona jest, na stosie kopia, operujemy na niej, po wyjściu z funkcji, a pozostaje nie zmienione.
f2, natomiast, przyjmuje wskażnik do integera, który wskazuje na konkretne miejsce w pamięci, dokonuje dereferencji *a i teraz operuje bezpośrednio na zawartości tego adresu (czyli zmienia bity a), dlatego na wyjściu mamy, w końcu finalne 42.
To samo jest w przypadku Linked Listy, zawsze Wysyłasz (bo head nim jest) wskaźnik, i znowu, (head->next to sugar za (*head).next) pointer, dereferencja, akcja, powrót.
Tak operujemy na obiektach, bo to jest właśnie defincja obiektu: Miejsce w pamięci, przechowujące jakiś typ wartości, do których można się odwołać, mając adres.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.