Śmieci w tablicy struktur

0

Witam,

Mam problem przy wstawianiu danych do tablicy struktur. Dane wczytuje z pliku, więc dzieje to się w pętli i tam są dobrze czytane. Gdy wyjdę poza zakres tej pętli i próbuje odczytać dane o tych samych indeksach to dostaje jakieś śmieci.

Mój kod:

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

#define M 100

struct words
{
    int nr;
    char* nazwisko;
} T[M];

int main()
{
int i;

// Wyzerowanie tablicy
for (i = 0; i < M; i++)
{
         T[i].nr= 0;
         T[i].nazwisko = '\0';
}

// Wstawianie do tablicy
FILE* nazwiska = fopen("nazwiska.txt", "r");
i = 0;
char word[256];
while (fgets(word, 255, nazwiska) != 0 && i != M)
{
       int nr = atoi(strtok( word, " " ));
       char* nazwisko = strtok( NULL, "\n" );
       T[i].nr= nr;
       T[i].nazwisko = nazwisko;
       printf("%i %s\n", T[i].nr, T[i].nazwisko); //tutaj poprawnie odczytuje dane
       i++;
}
fclose(nazwiska);

// Wyświetlenie tablicy
printf("ID\tNR\tNAZWISKO\n");
for (i = 0; i < M; i++)
      printf("%i\t%i\t%s\n", i, T[i].nr, T[i].nazwisko); //jednak już tutaj uzyskuje śmieci

return 0;
}

W pliku znajdują się dane w formacie <nr><spacja><nazwisko><znak_przejscia_do_kolejnej_linii> -> można go pobrać stąd - http://www.futrega.org/etc/nazwiska.zip (najlepiej zamienić polskie znaki na angielskie, żeby nie było problemów).
Co ciekawe T[i].nr wyświetla się poprawnie (porównywałem z plikiem), a T[i].nazwisko wyświetla zawsze 2 wyraz licząc od ostatniego przeglądanego i to nie zawsze cały. W czym może tkwić problem?

Z góry dziękuję za wszelką pomoc.

Pozdrawiam,
brando.

1

Zerowanie wywal - niepotrzebne i niepoprawne.

for(i=0;(fscanf(nazwiska," %d %^s",&T[i].nr,T[i].nazwisko)==2)&&(i<M);++i) printf("%i %s\n",T[i].nr,T[i].nazwisko);
0

Dzięki za odpowiedź.

Zerowanie zlikwidowałem i zastosowałem Twój kod. Jednak niestety coś nadal jest nie tak.

Teraz mam taki kod:

FILE* nazwiska = fopen("nazwiska.txt", "r");
int i;
int sukces;
for (i = 0;(((sukces = (fscanf(nazwiska,"%d %*s",&T[i].nr, T[i].nazwisko)))==2)||(i<M)); ++i)
          printf("%d %s %i\n", T[i].nr, T[i].nazwisko, sukces);
fclose(nazwiska);

Dzięki takiemu formatowaniu ignoruje mi nazwiska i wczytuje mi numery - to działa poprawnie również poza pętlą. Jak zlikwiduje * to wczyta mi tylko pierwszy numer, bez nazwiska i potem zmienna sukces wyświetla same zera, czyli niepowodzenie. Gdy zastosowałem formatowanie

"%d %^s"

to wyrzuciło ostrzeżenie: unknown conversion type character '^' in format. Próbowałem również formatowania: "%d %s\n"

, ale to nic nie daje. Myślę, że przyczyną jest tutaj tylko i wyłącznie formatowanie. Jakie powinno być poprawne trzymając się założenia - <nr><spacja><nazwisko><znak_przejscia_do_kolejnej_linii>?

Pozdrawiam,
brando.
1

Coś popsułes: http://ideone.com/9l8uT2

0

Ok, teraz działa wyświetlanie - zamieniłem w strukturze char* nazwisko na char nazwisko[].

Mam jeszcze jeden problem, ponieważ mam dodatkową funkcję do której przekazuje T[i].nazwisko i tu właśnie pojawia się problem, ponieważ wyskakuje naruszenie ochrony pamięci. Wygląda to mniej więcej tak:

//... deklaracja struktury jak poprzednio

void funkcja(char word[])
{
// kod
}

int main()
{
FILE* nazwiska = fopen("nazwiska.txt", "r");
int i;
int sukces;
for (i = 0;(((sukces = (fscanf(nazwiska,"%d %s\n",&T[i].nr, T[i].nazwisko)))==2)||(i<M)); ++i)
             funkcja(T[i].nazwisko); //takie wywołanie powoduje naruszenie ochrony pamięci
fclose(nazwiska);

return 0;
}

Chciałbym też zaznaczyć, że do tej funkcji przekazuje również normalne wyrazy nie tylko z tablicy struktur i funkcja wtedy działa normalnie. Wiem, że można by przekazywać wskaźnik na tą tablicę, ale wtedy nie mógłbym przekazywać wyrazów spoza tej tablicy. Więc wolałbym przekazywać wyraz od razu.

1

Moment, nie zauważyłem że masz char *nazwisko więc musisz przydzielać pod to pamięć.

char buff[100];
for(i=0;(((sukces=(fscanf(nazwiska," %d %99s",&T[i].nr,buff)))==2)||(i<M));++i) T[i].nazwisko=strdup(buff);
fclose(nazwiska);
for(k=0;k<i;++k) printf("%d %s\n",T[k].nr,T[k].nazwisko);
for(k=0;k<i;++k) free(T[k].nazwisko);
1

Tak przy okazji

char *nazwisko = "nazwisko";
printf("%d %s\n", numer, nazwisko);

To też działa, więc co innego popsułeś.

0

Wielkie dzięki - już wszystko działa :)

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