Strona 1 z 1

[ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 13:14
autor: wojtos93
Cześc, napotkałem kolejny problem związany z programowaniem w C. Mój program ma zamieniać wszystkie przecinki w pliku wejściowym i zapisywać do pliku wyjściowego tekst z kropkami. Bardziej chodzi o liczby - po zamianie separator dziesiętny ma być kropką. Plik wyjściowy wygląda dobrze, ale na jego końcu program dodaje "/FF", a gedit mówi, że wystąpił błąd otwierania pliku. Wygląd plików przed (po prawej) i po (po lewej) zamianie.
Zrzut

a tu kod:

Kod: Zaznacz cały

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

int main()
{
	char z;
	double i = 0, j = 0, k = 0;

	FILE *plik, *plikWy;

	plik = fopen("plika", "r");
	while( !feof(plik) )
	{
		z = fgetc(plik);
		k++;
		if(z == ',')
		{
			plikWy = fopen("plikb", "w");
			z = '.';
			for(i = 0; i < k; i++)
				putc(z, plikWy);
		}
		else
		{
			plikWy = fopen("plikb", "w");
			for(i = 0; i < k; i++)
				putc(z, plikWy);
		}
	}
	fclose(plik);
	fclose(plikWy);

	return(0);
}
Edit: poza tym program nie działa dla dużej ilości przecinków (wywala: naruszenie ochrony pamięci).

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 13:26
autor: ethanak
wybacz ale większej bzdury w życiu nie widziałem - a uwierz mi, widziałem chyba więcej bzdur niż makaronu zjadłem...
podałbym rozwiązanie ale po takiej traumie muszę się natychmiast czegoś napić.

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 13:43
autor: wojtos93
Wybacz, ale jestem początkujący. Napij się i uspokój.

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 13:51
autor: ethanak
oj już po piwku trochę lepiej... chociaż jeszvze serduszko się nie uspokoiło...

zrób jedną rzecz: weź swój kod i do każdej linii dodaj komentarz wyjaśniający co robi. jeśli pi przeczytaniu nie będziesz wiedział dlaczego jest to bzdura, zamieść komentowany kod tutaj, postaram się jakoś pomóc.
uprzedzając pytania:
a. tak, chcę pomóc a nie śmiać się z początkującego
b. chętnych programistych którzy chcą pokazać jacy są genialni i tego jednolinijkowca w c tutaj zamieścić proszę o rozwagę, bo krzywdę komuś wyrządzicie.

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 14:01
autor: wojtos93

Kod: Zaznacz cały

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

    int main()
    {
       char z;                                    //zmienna, do której wczytywany jest znak z pliku wejściowego
       double i = 0, j = 0, k = 0;       //zmienna j - jest zbędna, k i i do pętli

       FILE *plik, *plikWy;           //wskaźniki do plików we i wy

       plik = fopen("plika", "r"); //otwiera plik w trybie do odczytu
       while( !feof(plik) )       //powtarza pętlę aż do końca plików
       {
          z = fgetc(plik);       //pobiera pierwszy znak z pliku we
          k++;               //liczy znaki
          if(z == ',')              //jeśli znak jest przecinkiem:
          {
             plikWy = fopen("plikb", "w");   //otwórz plik wy w trybie do zapisu
             z = '.';   //zamienia przecinek na kropkę
             for(i = 0; i < k; i++)    //pętla, która w odpowiednim miejscu w pliku wstawia odpowiedni znak
                putc(z, plikWy);      //  w tej pętli może być coś nie tak
          }
          else  //jeśli znak jest inny niż przecinek, wpisz do nowego pliku ten znak
          {
             plikWy = fopen("plikb", "w");
             for(i = 0; i < k; i++)    // w tej też coś nie tak
                putc(z, plikWy);
          }
       }
       fclose(plik);   //zamknij
       fclose(plikWy);

       return(0);
    }

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 14:12
autor: ethanak
doping:

Kod: Zaznacz cały

for (i=0;i<k:i++) fputc(z,f);
wstawi string złożony z wczytanych uprzednio znaków czy może string złożony z k tych samych znaków z?
pytanie kontrolne: dlaczego uważasz, że plik wyjściowy należy wykasować i otworzyć do zapisu za każdym razem gdy w wejściowym napotkasz przecinek?

przy okazji: double jest do obliczeń zmiennoprzecinkowych. wyobrażasz sobie sytuację, że k w twoim programie przyjmie wartość np. 3.14?

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 14:37
autor: wojtos93
Wstawi k razy tych samych z.
Plik wyjściowy kasowany? Chodzi Ci o to, żeby wstawić otwieranie go przed while i przed if? Teraz muszę popracować nad tą pętlą, bo w pliku wyjściowym za dużo wszystkiego.
Nie ma opcji, żeby k = 3.14, bo rośnie o 1; fakt, chyba mogę zastosować int.

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 14:43
autor: ethanak
dokładnie: plik wyjściowy ma być otwarty raz przed główną pętlą. ponieważ wewnętrzne pętle (jak sam zauważyłeś) nie są potrzebne, nie są potrzebne również zmienne pomocnicze - czyli nieważne czy double czy int bo i tak ich nie ma.
zauważ jeszcze jedno: fgetc zwraca wartość int a nie char. szczególnie może zwrócić EOF czyli wartość spoza zakresu char.

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 15:08
autor: wojtos93

Kod: Zaznacz cały

#include <stdio.h>
#include <stdlib.h>
int main()
{
	char z;
	int i = 0;
	FILE *plik, *plikWy;

	plik = fopen("plika", "r");
	plikWy = fopen("plikb", "w");
	while( !feof(plik) )
	{
		z = getc(plik);
		if(z == ',')
		{
			z = '.';
			putc(z, plikWy);
		}
		else
		{
			putc(z, plikWy);
		}
	}
	fclose(plik);
	fclose(plikWy);
	return(0);
}
A co do tego co powiedziałeś na końcu, to dlatego wywala taki dziwny znak /FF na końcu pliku? Chce zwrócić EOF, a nie może go wyświetlić, więc wywala błąd. W takim razie z czego powinienem skorzystać? fgets?

Chyba, że zmienną z zmienię na int

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 15:16
autor: ethanak
wędka:

Kod: Zaznacz cały

while ((z=fgetc(plik)) != EOF) {...}
wystarczy?
oczywiście int z - EOF (-1) castowane na uchar to 0xff.

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 15:19
autor: wojtos93
Właśnie przed chwilą to napisałem, dziękuję ethanak :)

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 18:58
autor: beluosus
W if-else niepotrzebnie powtarzasz instrukcję, wyciągnij za nawias:

Kod: Zaznacz cały

if (',' == z)  // jakby nam przypadkowo jeden "=" umknął to kompilator będzie krzyczał, że wymaga lvalue
{
	z = '.';
}
putc(z, plikWy);
albo (zależnie od potrzeb):

Kod: Zaznacz cały

if (',' == z)
{
	putc('.', plikWy);
}
else
{
	putc(z, plikWy);
}
Jak Ci się nudzi to zrób jeszcze sprawdzanie ferror (na obu plikach). ;)

PS
ethanak pisze:b. chętnych programistych którzy chcą pokazać jacy są genialni i tego jednolinijkowca w c tutaj zamieścić proszę o rozwagę, bo krzywdę komuś wyrządzicie.
;-)

Kod: Zaznacz cały

while ((z=fgetc(plik)) != EOF) putc(z==','?'.':z, plikWy);

Re: [ C ] Zamiana przecinków na kropki w pliku

: 11 cze 2013, 20:45
autor: wojtos93
Już jest prawie wszystko git, ale nadal nie wiem jak się pozbyć dodawanego \FF na końcy pliku wyjściowego. Jakbyście mi mogli łopatologicznie wyjaśnić to byłbym wdzięczny.

Re: [ C ] Zamiana przecinków na kropki w pliku

: 12 cze 2013, 07:18
autor: ethanak
Łopatologicznie to jeszcze jednej rzeczy nie poprawiłeś, a obaj Ci pokazywaliśmy.
Funkcja feof zwraca po prostu stan znacznika end-of-file dla strumienia. znacznik ten jest ustawiany dopiero po próbie wczytania znaku poza końcem pliku (fakt, dokumentacja jest nieco niejasna). Czyli w efekcie Twój program działa tak (pseudojęzyk):

Kod: Zaznacz cały

1. czy wystąpiła próba czytania poza końcem pliku? Jeśli nie, to:
  2. wczytaj znak
  3. wypisz ten znak albo kropkę
  4. wróć do 1
Czyli najpierw sprawdzasz czy napotkano koniec, dopiero później wczytujesz znak. Nic dziwnego że ostatnim zwracanym znakiem jest EOF czyli to Twoje nieszczęsne FF.
A teraz porównaj czym się różni Twoja pętla od mojej czy kolegi @beluosus.

Re: [ C ] Zamiana przecinków na kropki w pliku

: 12 cze 2013, 13:48
autor: wojtos93
Aaa, dodałem po wczytaniu znaku sprawdzenie if( z != EOF) i jeśli się zgadza to zamienia znaki, a jeśli nie to koniec pracy. Dzięki jeszcze raz.