kopiowanie danych z pliku do tablicy dynamicznej

0

Witam,
Od niedawna uczę się programować w C. Napotkałem problem z takim oto zadaniem:
5. Napisz program, który odczyta plik złożony z liczb całkowitych i skopiuje odczytane liczby do komórek tablicy dynamicznej. Tablica powinna mieć wielkość dostosowaną do liczby odczytanych elementów z pliku. Nazwa pliku powinna zostać podana z linii poleceń.
Napisałem kawałek takiego kodu:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
FILE *source;
int a, licznik, rozmiar;
char *tablica;
rozmiar=0;
if((source=fopen(argv[1],"r"))==NULL)
return -1;
while(fscanf(source,"%d",&a)==1)
rozmiar++;
if((tablica=(char *)malloc(rozmiar))==NULL)
return -1;
printf("%d liczb zostanie skopiowanych!\n",rozmiar);
for(licznik=0;licznik<rozmiar;licznik++){
fscanf(source,"%d",tablica);
tablica++;
}
puts(tablica);
fclose(source);
free(tablica);
return 0;
}

Mam już zrealizowany rozmiar zależny od liczby odczytanych elementów z pliku, co wiązało się z przeczytaniem całego pliku. Niestety program nie działa jak należy tzn. nie ma błędów ale tablica ma w sobie jakieś dziwne wartości zamiast tych liczb, które są w pliku. Może ktoś by mi podsunął pomysł jak mógłbym to zadanie wykonać?

0

fseek

0

W podręczniku w którym było to zadanie (a czytam rozdział po rozdziale i na końcu każdego rozdziału są ćwiczenia) nie ma wzmianki o funkcji fseek. Nie da się tego zrealizować jakoś inaczej np. przy jednorazowym przeczytaniu pliku bez konieczności ustawiania pozycji w pliku na 0?

0

Można: zamykasz plik, otwierasz ponowne.

0

Nie wychodzi :(
No nic, będę jutro kombinował, póki co przez noc pozostanie niedosyt.

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
FILE *source;
int a, licznik, rozmiar;
int *tablica;
rozmiar=0;
if((source=fopen(argv[1],"r"))==NULL)
return -1;
while(fscanf(source,"%d",&a)==1)
rozmiar++;
if((tablica=(int *)malloc(rozmiar*sizeof(int)))==NULL)
return -1;
printf("%d liczb zostanie skopiowanych!\n",rozmiar);

/*zamknalem plik*/
fclose(source);

/*otworzylem plik*/
source=fopen(argv[1],"r");

for(licznik=0;licznik<rozmiar;licznik++){
fscanf(source,"%d",tablica);
tablica++;
}
puts(tablica);
fclose(source);
free(tablica);
return 0;
}

.. a oto efekt:

au7h@l0c4lh0st:~/Dokumenty/CWICZENIA/cw5$ ./a.out zrodlo
18 liczb zostanie skopiowanych!

*** glibc detected *** ./a.out: munmap_chunk(): invalid pointer: 0x08f661b8 ***
======= Backtrace: =========
/lib/i686/cmov/libc.so.6(+0x6af71)[0xb76ddf71]
/lib/i686/cmov/libc.so.6(+0x6c1ee)[0xb76df1ee]
./a.out[0x804865e]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb7689ca6]
./a.out[0x80484a1]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 582545     /home/au7h/Dokumenty/CWICZENIA/cw5/a.out
08049000-0804a000 rw-p 00000000 08:01 582545     /home/au7h/Dokumenty/CWICZENIA/cw5/a.out
08f66000-08f87000 rw-p 00000000 00:00 0          [heap]
b7643000-b7660000 r-xp 00000000 08:01 6889475    /lib/libgcc_s.so.1
b7660000-b7661000 rw-p 0001c000 08:01 6889475    /lib/libgcc_s.so.1
b7672000-b7673000 rw-p 00000000 00:00 0 
b7673000-b77b3000 r-xp 00000000 08:01 6905889    /lib/i686/cmov/libc-2.11.3.so
b77b3000-b77b4000 ---p 00140000 08:01 6905889    /lib/i686/cmov/libc-2.11.3.so
b77b4000-b77b6000 r--p 00140000 08:01 6905889    /lib/i686/cmov/libc-2.11.3.so
b77b6000-b77b7000 rw-p 00142000 08:01 6905889    /lib/i686/cmov/libc-2.11.3.so
b77b7000-b77ba000 rw-p 00000000 00:00 0 
b77c9000-b77ca000 rw-p 00000000 00:00 0 
b77cb000-b77cd000 rw-p 00000000 00:00 0 
b77cd000-b77ce000 r-xp 00000000 00:00 0          [vdso]
b77ce000-b77e9000 r-xp 00000000 08:01 6890016    /lib/ld-2.11.3.so
b77e9000-b77ea000 r--p 0001b000 08:01 6890016    /lib/ld-2.11.3.so
b77ea000-b77eb000 rw-p 0001c000 08:01 6890016    /lib/ld-2.11.3.so
bf80e000-bf823000 rw-p 00000000 00:00 0          [stack]
Przerwane
0
puts(tablica); // kompletny WTF
free(tablica); // przecież już ją zepsułeś przez serię ++ po scanf
0

Z tym puts fakt. A sens tych ++ pod fscanf był według mnie jest taki, by przesuwać się po adresie tablicy o 1, po to żeby zapisywać po jednej liczbie do kolejnych elementów tablicy dynamicznej, a nie ciągle do tego samego elementu tej tablicy.

Trochę poprawiłem programik :P
Dodałem tablicę, ale już nie dynamiczną niestety a co za tym idzie, jej wielkość nie jest dostosowana do liczby odczytanych znaków,ale przynajmniej działa

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
FILE *source;
int a, licznik, rozmiar;
int *tablica;
int xd[55];                                                           // tablica :)
rozmiar=0;
if((source=fopen(argv[1],"r"))==NULL)
return -1;
while(fscanf(source,"%d",&a)==1)
rozmiar++;
if((tablica=(int *)malloc(rozmiar*sizeof(int)))==NULL)
return -1;
printf("%d liczb zostanie skopiowanych!\n",rozmiar);
fclose(source);
source=fopen(argv[1],"r");
for(licznik=0;licznik<rozmiar;licznik++)
fscanf(source,"%d",&xd[licznik]);

for(licznik=0;licznik<rozmiar;licznik++)
printf("%d ", xd[licznik]);

printf("\n");
fclose(source);
free(tablica);
return 0;
}

efekt:

au7h@l0c4lh0st:~/Dokumenty/CWICZENIA/cw5$ ./a.out zrodlo
18 liczb zostanie skopiowanych!
45 322 4 2345 21 84 666 1 2 54 3 4 57 21 2 1 78 7 
au7h@l0c4lh0st:~/Dokumenty/CWICZENIA/cw5$
1

Wywal deklaracje xd, resztę wystąpień xd zamień na tablica.

0

Działa jak natura chciała, dzięki wielkie!
:)

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