Przeiterowanie po liście jednokierunkowej

0

Utworzyłem listę jednokierunkową:

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.

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:

while (head->next != nullptr)

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

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/

0

@YooSy: Próbuję też tak:

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";
}
2
void do_sth(node * head){
    node * tmp = head;
    while(tmp) {
        /* Do sth with tmp */
        tmp = tmp->next;
    }
}
// main:
do_sth(list_head);
2
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

Node *pointerek = nullptr;
     CreateFiles(pointerek); 

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

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.

0

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

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

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