[ C ] Zamiana przecinków na kropki w pliku

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
wojtos93
Sędziwy Jeż
Sędziwy Jeż
Posty: 74
Rejestracja: 21 maja 2008, 12:14
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86_64
Kontakt:

[ C ] Zamiana przecinków na kropki w pliku

Post 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).
Ostatnio zmieniony 11 cze 2013, 13:29 przez wojtos93, łącznie zmieniany 1 raz.
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

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

Post 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ć.
wojtos93
Sędziwy Jeż
Sędziwy Jeż
Posty: 74
Rejestracja: 21 maja 2008, 12:14
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86_64
Kontakt:

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

Post autor: wojtos93 »

Wybacz, ale jestem początkujący. Napij się i uspokój.
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

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

Post 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.
wojtos93
Sędziwy Jeż
Sędziwy Jeż
Posty: 74
Rejestracja: 21 maja 2008, 12:14
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86_64
Kontakt:

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

Post 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);
    }
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

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

Post 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?
wojtos93
Sędziwy Jeż
Sędziwy Jeż
Posty: 74
Rejestracja: 21 maja 2008, 12:14
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86_64
Kontakt:

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

Post 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.
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

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

Post 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.
wojtos93
Sędziwy Jeż
Sędziwy Jeż
Posty: 74
Rejestracja: 21 maja 2008, 12:14
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86_64
Kontakt:

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

Post 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
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

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

Post 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.
wojtos93
Sędziwy Jeż
Sędziwy Jeż
Posty: 74
Rejestracja: 21 maja 2008, 12:14
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86_64
Kontakt:

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

Post autor: wojtos93 »

Właśnie przed chwilą to napisałem, dziękuję ethanak :)
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

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

Post 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);
wojtos93
Sędziwy Jeż
Sędziwy Jeż
Posty: 74
Rejestracja: 21 maja 2008, 12:14
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86_64
Kontakt:

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

Post 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.
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

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

Post 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.
wojtos93
Sędziwy Jeż
Sędziwy Jeż
Posty: 74
Rejestracja: 21 maja 2008, 12:14
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86_64
Kontakt:

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

Post 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.
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 56 gości