dzialania na plikach txt z uzyciem tablicy dynamicznej

0

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

int main(int argc, char *argv[])
{
int a=1;
int i=0;
int licznik_a=0,licznik_linijki=1;
char *tekst;
char *szczerze_mowiac_to_nie_wiem_czy_to_konieczne_ale_zobaczymy_wesolych_swiat;
FILE *fp;
FILE *zapis;
fp=fopen("plik.txt","r");
zapis=fopen("wynik.txt","w");
if(fp==NULL)
{
printf("plik.txt nie istnieje\n");
system("PAUSE");
return 0;
}

//odzytanie liter "a" z pliku i wypisanie ich ilosci
while(a)
{
	tekst=(char*) malloc(sizeof(*szczerze_mowiac_to_nie_wiem_czy_to_konieczne_ale_zobaczymy_wesolych_swiat));
	fscanf(fp,"%c",&tekst[i]);
	if(feof(fp) == 0)
	{
		if(tekst[i]=='a')
		{   
		   licznik_a++;       
		}  
		if(tekst[i]==10)
		{
			printf(" linijka %d: %d\n", licznik_linijki, licznik_a);
			fprintf(zapis,"linijka %d: %d\n",licznik_linijki, licznik_a);
			licznik_a=0;
			licznik_linijki++;
		}         
		i++;
	}else a=0;
}
//////////////////////////////////////////////////
printf("koniec pliku\n");
fclose(fp);
fclose(zapis);
free(tekst);
system("PAUSE");
return 0;

}

Plik.txt:
a a a a
s s s
d a d a

wynik dzialania programu:
linijka 1: 4
linijka 2: 0
Koniec pliku

Dlaczego nie czyta linijki trzeciej??

0

i w ogóle ten program dla wiekszej ilosci linijek sie zwiesza

1

Alokujesz pamięć dla jednego znaku (zmienna tekst - sizeof(char)), a zachowujesz się jak gdyby to była tablica.

2
  1. Nie używaj postinkrementacji bez potrzeby: http://4programmers.net/Forum/1101404
  2. Po kiego przydzielasz jakąś pamięć skoro i tak czytasz znak po znaku i tylko ten znak analizujesz?
  3. Czy udało się otworzyć plik do odczytu skrupulatnie sprawdzasz, zaś czy udało się otworzyć plik do zapisu już nie, WTF?
  4. Takie podejście while((ch=fgetc(fp))!=EOF) dla odczytu pliku znak po znaku jest sensowne, alternatywa - czytanie do bufora np po 2K
  5. Jeżeli warunki nie mogą się pokrywać to ma sens zastosować else if lub przynajmniej switch()
  6. Jeżeli potrzebujesz system("PAUSE"); oznacza to tylko jedno - masz IDE z poprzedniego tysiąclecia (dosłownie), może ściągnij nowsze.
  7. Zapamiętaj prostą regułę: - free() ma wykonać się tyle samo razy malloc() ( owszem są odstępstwa ale to nie ten poziom )
0

Zdumiewający jesteś xD Wrzuciłeś jakiś rozmemłany kod, i praktycznie nie zadałeś żadnego konkretnego pytania.

0

@_13th_Dragon
1.nie wiedzialem
2.ok widze blad
3.jak nie ma pliku do zapisu to on sie sam tworzy wiec wydaje mi sie ze nic sie nie moze stac
4.
5.masz racje
6. uzywam dev c++ 5.11
7.ok, nie wiedzialem

1

Plik może się nie stworzyć w wyniku:

  • niedozwolony znaki w nazwie
  • brak uprawnień do zapisu
  • oraz ewentualny błąd systemu
    dev c++ 5.11 - pozostawia ekran po zamknięciu, więc zwyczajnie wywal ten system("PAUSE");
0

**Bazując na waszych wypowiedziach napisalem cos takiego jak wyżej, wszystko dziala, zostawiam dla innych zaciekawionych, zachecam do oceniania i krytyki
**

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

int main(int argc, char *argv[])
{
FILE *wczytanie;
FILE *zapis;
int i=0;
int licznik_a=0,licznik_linijki=1;
char tab[1];
wczytanie=fopen("plik.txt","r");
zapis=fopen("wynik.txt","w");
//Mechanizm kontroli bledow plikow do wczytania i zapisu
if(wczytanie==NULL)
{
printf("plik do wczytania nie istnieje\n");
return 0;
}
if(zapis==NULL)
{
printf("plik do zapisu nie istnieje\n");
return 0;
}
//Wczytanie liter z pliku i zapis do pliku wynik.txt
while(feof(wczytanie)==0)
{
fscanf(wczytanie,"%c",&tab[0]);
if(tab[0]==10||feof(wczytanie)!=0)
{
printf("linijka %d:%d\n",licznik_linijki,licznik_a);
fprintf(zapis,"linijka %d:%d\n",licznik_linijki,licznik_a);
++licznik_linijki;
licznik_a=0;
}
if(tab[0]=='a')
{
++licznik_a;
}
}
//Zamkniecie plikow i zakonczenie programu
fclose(wczytanie);
fclose(zapis);
return 0;
}

2
  1. Tak w sumie to dlaczego tab jest tablicą?
  2. Oprócz tego wykorzystujesz dziwne nazewnictwo (dlaczego kurczę belka jedna zmienna to wczytywanie, a druga to zapis? Trzecia to byłoby pewnie coś w stylu odczytawszy :P).
  3. Wiesz dlaczego funkcja main zwraca int, czy nie zainteresowałeś się tym? Bo na oko to nie masz bladego pojęcia.
1

Potraktuj to jako kontynuacje tego co @Patryk27 nie dopisał.

  1. Ja wolę taki zapis:
if(!(zapis=fopen("wynik.txt","w"))) return 0<=fprintf(stderr,"plik do wczytania nie istnieje\n");

od razu widać akcję oraz reakcję.
2. Przejrzyj sobie to:

while(!feof(wczytanie))
  {
   int ch=fgetc(wczytanie);
   if(ch=='a') ++licznik_a;
   else if((ch=='\n')||(ch==EOF))
     {
      ...
     }
  }
0

@Patryk27

  1. no tak mozna bylo uzyc czegokolowiek
  2. nie zwrocilem na to uwage
  3. nie mam bladego pojecia

@_13th_Dragon
dziekuje, przejrze

0

Ad 1. Jak przejrzysz to co napisałem to zobaczysz odpowiedź.
Ad 3. W przypadku błędów raczej należy zwrócić nie 0 aby system mógł się o tym dowiedzieć.

1

no tak mozna bylo uzyc czegokolowiek
No może nie czegokolwiek, ale jaki sens ma deklarowanie na stałe tablicy jednoelementowej? Robisz sobie kłopotu zamiast po prostu napisać char tab;. Pomijam już oczywiście to, że ta zmienna jest słabo nazwana.

nie zwrocilem na to uwage
Zatem najwyższa pora. Nie sztuką klepać kod, a pisać go tak, aby był czytelny i dla innych.

nie mam bladego pojecia
Podczas nauki istotne jest dociekanie szczegółów - nie będziesz dobrym programistą omawiając wszystko po łebkach, więc leć prędko do dokumentacji i zapoznaj się z tym.

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