Kopiowanie co trzeciego znaku z jednego pliku do drugiego

0

Problem jest w tym programie. Program ma za zadanie skopiować co 3ci znak z jednego pliku i wstawić go do drugiego. Jest to jeden z listingów w książce Język C szkoła programowania, z tym, że ma modyfikacje. Po uruchomieniu programu nie dostaję żadnych informacji od programu. Program uruchamiany na Ubuntu 14.04


/*
 * rozdzial13L2.c
 *
 *  Created on: 30-03-2014
 *      Author: dawid
 */

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

#define ARG_ERR "Użycie: %s nazwa_pliku\n"
#define FOPEN_ERR "Nie można otworzyć pliku: %s\n"
#define FCLOSE_ERR "Nie można zamknąć plików\n"

int arg_lengh(char arg[]); //sprawdza długość tablicy


int main(int argc, char *argv[])
{
	FILE * file_src, *file_destin;
	int ch;
	char nazwa[arg_lengh(argv[1]) + 4]; // rezerwuje miejsce o 4 większe, aby do nazwy pliku końcowego dodać .red
	int licznik = 0;
	int nazwa_lengh = arg_lengh(argv[1]);

	//sprawdza poprawne wywołanie programu
	if (argc != 2)
	{
		fprintf(stderr,ARG_ERR, argv[0]);
		exit(1);
	}

	//sprawdza błędy otworzenia pliku źródłowego
	if ((file_src = fopen(argv[1], "r")) == NULL)
	{
		fprintf(stderr, FOPEN_ERR, argv[1]);
		exit(2);
	}

	//Ustawia nazwę pliku wyjściowego
	strcpy(nazwa,argv[1]);
	if (nazwa[nazwa_lengh] == '.')
		strcat(nazwa, "red");
	else
		strcat(nazwa, ".red");

	//sprawdza błędy otworzenia nowego pliku
	if ((file_destin = fopen(nazwa, "w"))== NULL)
	{
		fprintf(stderr,FOPEN_ERR,nazwa);
		exit(3);
	}

	//Kopiuje do pliku docelowego co trzeci znak
	while ((ch = getc(file_src)) != EOF)
	{
		if (licznik % 3 == 0)
			putc(ch,file_destin);
	}

	// Sprawdza poprawne zamknięcie plików
	if ((fclose(file_src) != 0) || (fclose(file_destin) != 0))
	{
		fprintf(stderr,FCLOSE_ERR);
		exit(3);
	}

	return EXIT_SUCCESS;
}


int arg_lengh(char arg[])
{
	int lengh = 0;

	//sprawdza długość nazwy do końca łańcucha lub napotkania kropki
	while(arg[lengh] != '\0' || arg[lengh] != '.')
		lengh++;

	return lengh;
}

Próbowałem w kodzie w różnych miejscach wstawiać printf("1"), żeby zobaczyć przynajmniej do którego miejsca program dochodzi ale nic nie zostało wyświetlone niestety. printf wstawiałem zarówno w różnych miejscach funkcji main jak i w funkcji arg_lengh. Z góry dziękuję za poświęcony czas i odpowiem (jeśli będę potrafił) na zadane pytania

1

Masz jeszcze nie opanowane cstring'i oraz przydzielenie pamięci:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define ARG_ERR "Użycie: %s nazwa_pliku\n"
#define FOPEN_ERR "Nie można otworzyć pliku: %s\n"
#define FCLOSE_ERR "Nie można zamknąć plików\n"
 
int arg_lengh(const char *arg)
  {
   const char *ptr=arg;
   while((*ptr)&&(*ptr!='.')) ++ptr;
   return ptr-arg;
  } 

void check_err(int err,int code,const char *msg,const char *param)
  {
   if(!err) return;
   fprintf(stderr,msg,param);
   exit(code);
  }
 
int main(int argc, char *argv[])
  {
   FILE * file_src, *file_destin;
   char *nazwa;
   int ch,len;
     
   check_err(argc!=2,1,ARG_ERR,argv[0]);
   check_err(!(file_src=fopen(argv[1], "r")),2,FOPEN_ERR,argv[1]);
   len=arg_lengh(argv[1]);
   nazwa=(char*)malloc(len+5); // 4 znaki oraz znak końca
   strcpy(nazwa,argv[1]);
   strcpy(nazwa+len,".red");
   check_err(!(file_destin = fopen(nazwa, "w")),3,FOPEN_ERR,nazwa);
   free(nazwa);
   while ((ch=getc(file_src))!=EOF)
     {
      getc(file_src);
      getc(file_src);
      putc(ch,file_destin);
     }
   check_err(fclose(file_src)!=0,4,FCLOSE_ERR,NULL);
   check_err(fclose(file_destin)!=0,4,FCLOSE_ERR,NULL);
   return EXIT_SUCCESS;
  }
0

Dziękuję za odpowiedź. Mam kilka pytań. Dlaczego muszę użyć funkcji malloc(), a nie mogę użyć po prostu tablicy VLA? Nie rozumiem dlaczego też nie mogłem użyć funkcji strcat(), bo o ile dobrze rozumiem dopisuje on łańcuch który był na prawo jako argument do końca lewego, więc powinno według mnie działać, ale jak widać nie działa. jeżeli chodzi o wyrażenie :

while((*ptr)&&(*ptr!='.')) ++ptr;

rozumiem tak: Jeżeli wartość elementu na który wskazuje ptr jest równy zero i wartość tego elementu jest różna od znaku kropki. Według mojego błędnego myślenia to wyrażenie zawsze będzie fałszem poza sytuacją, gdzie wartość będzie 0, bo i pierwszy i drugi warunek będzie spełniony, więc wtedy pętla się wykona, a reszta sytuacji na mój rozum będzie fałszywa, bo pierwszy warunek nie będzie spełniony. Byłbym wdzięczny, gdyby ktoś mi to wytłumaczył. Bardzo dziękuję jeszcze raz za poprawienie kodu :)

1
  1. malloc() - zadziała w każdym kompilatorze od C do C++, tablica nieznanego podczas kompilacji rozmiaru - tylko pod C99
  2. strcat - działa jak należy z tym że strcpy(nazwa,argv[1]); kopiuje cały parametr razem z rozszerzeniem do którego doklejałeś "red"
  3. (*ptr) - jeżeli znak pod ptr NIE jest zerem.
0

Bardzo Ci dziękuję :)

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