Jump to content

Recommended Posts

Posted

Boas,

á aproximadamente 1 ano comecei a programar em c pela primeira vez, por isso ainda não tenho muita experiência, no entanto, tenho desenvolvido alguma ideias que considero interessantes.

Uma dessa ideias venho-a partilhar aqui com vocês, para me darem opiniões e feedback de forma a a poder melhorar.

Este programa chama-se total deleter e como o próprio nome indica tem como função eliminar totalmente da memoria um qualquer ficheiro, reescrevendo-o totalmente, de forma a nunca mais poder ser recuperado.

#include <stdio.h>
#include <conio.h>

int numdigits(int n){ //devolve o numero de digitos de um numero, ex 12345 = 5
return log10(n) + 1;
}

int calcmodulo(int numero_tamanho){//devolve 1 com um numero de zeros á frente igual ao de numero_tamanho
int modulo = 1;
while(numero_tamanho != 1){
 modulo = modulo * 10;
 numero_tamanho--;
 }
return modulo;
}

int getFileSize(FILE *input){ //dá o numero de bytes de um ficheiro
int fileSizeBytes;
fseek(input, 0, SEEK_END);
fileSizeBytes = ftell(input);
fseek(input, 0, SEEK_SET);
return fileSizeBytes;
}

void remove_char(char *string){ //função que remove primeiro e ultimo caracters de uma string
int idxToDel = 0;
memmove( &string[ idxToDel ] ,&string[ idxToDel+1 ], strlen(string) - idxToDel);
idxToDel = strlen(string)-1;
memmove( &string[ idxToDel ] ,&string[ idxToDel+1 ], strlen(string) - idxToDel);
}

int main() {
FILE *fp;
//char *vector_tamanho;
int i;
char file_name[500];
int modulo;
char *null;
null = (char *) calloc(0, sizeof(char)); //null é um carater com NULL


printf("\t\t\t|---------------------------------|\n");
printf("\t\t\t|		 TotalDeleter		 |\n");
printf("\t\t\t|---------------------------------|\n");
printf("\t\tThis program eliminates a file from memory permanently\n\n\n");
printf("The file path can not contain special characters.\n");
printf("Drag the file to this prompet:\nPath: ");

gets(file_name);
printf("\n");

if(file_name[0] == '"')//caso o caminho esteja envolvido em aspas
remove_char(file_name);

fp=fopen(file_name, "r+");
if (fp==NULL)
perror ("The following error occurred");

long long int tamanho_ficheiro = getFileSize(fp);

if (tamanho_ficheiro == -1)
{
printf("Invalid path!\n");
system("pause");
return 0;
}

printf("Size = %d bytes\n", tamanho_ficheiro);


printf("File open.\n");

printf("\n");
printf("Erase? ");
system("pause");




modulo = calcmodulo(numdigits(tamanho_ficheiro));
long long int cont = tamanho_ficheiro;


printf("0%%\n");
while(cont >= 0){
fwrite(null, sizeof(char), 1, fp);
if(cont % modulo == 0 )
printf("%d%%\n", 100-((cont*100)/tamanho_ficheiro)); //printa o loading do processo
cont--;

}

fclose(fp);
printf("File overwritten.\n");
//system("pause");//PARA DAR TEMPO DE VERIFICAR SE O FICHEIRO FOI DEVIDAMENTE RESCRITO antes de acabar o programa
remove(file_name);
printf("file deleted.\n");
system("pause");
return 0;
}

ficheiro compilado.exe

EU sei que este exercício pode parecer duvidoso mas acreditem é puramente académico

Posted

Não, nunca testei em linux, no entanto para testar teria de pelo menos tirar os system("pause"); nao sei se haveriam outras incompatibilidades... No entanto qual é o objectivo de testar em linux?

- conio.h : não existe (se bem que nem estou a ver porque estás a incluir isso)

- log10() : nem sei como compila no windows sem uma referência a esta função

- system() : já referiste

- remove() : é uma espécie de supra função para o unlink e o rmdir, se estás a apagar ficheiros usa diretamente o unlink

- remove_char() : não é um nome explítico do que a função realmente faz

- gets() : é uma função que deve ser evitada usando a sua substituta mais segura > fgets

- barra de progresso : existe maneira mais simples para apresentar isso sem essa matemática toda a baralhar

- indentação : não sei se foi por estás pouco habituado a fazer post de código, mas a indentação é inexistente

- c99 : eu compilo os meus projectos em c89 (sou piquinhas em relação a isso), logo não iria conseguir compilar (isto não é erro)

por alto será isto ...

IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

HHH,

Não há grande mal em usar-se C99, visto que o suporte para o mesmo já é decente nos compiladores mais utilizados. Não estive a ver com grande detalhe, mas pareceu-me que de C99 ele só utilizou os comentários //. O problema é grande parte das pessoas utilizarem sem saber tudo o que são extensões dos compiladores, isso concordo.

Quanto ao unlink, penso que essa só funciona em linux (é parte da unistd.h), mas corrige-me se estiver errado.

mastercgmr, além dos pontos já referidos pelo HHH, uma coisa que achei piada (alocar 0 elementos do tamanho de um char):

char *null;
null = (char *) calloc(0, sizeof(char)); //null é um carater com NULL

// e porque não assim?
char null = '\0';
Edited by pwseo
Posted

Não há grande mal em usar-se C99, visto que o suporte para o mesmo já é decente nos compiladores mais utilizados. Não estive a ver com grande detalhe, mas pareceu-me que de C99 ele só utilizou os comentários //. O problema é grande parte das pessoas utilizarem sem saber tudo o que são extensões dos compiladores, isso concordo.

vê bem, eu disse que era piquice minha e que não era erro nenhum.

no entanto digo-te que existe também a declaração de variáveis no meio do código, algo que o c89 não gosta

// ...
if (fp==NULL)
 perror ("The following error occurred");

long long int tamanho_ficheiro = getFileSize(fp);
// ...

Quanto ao unlink, penso que essa só funciona em linux (é parte da unistd.h), mas corrige-me se estiver errado.

na realidade a Microsoft achou que o unlink é "deprecated" e para isso criou a fenomenal função _unlink exactamente igual

http://msdn.microsoft.com/en-us/library/1c3tczd6.aspx

IRC : sim, é algo que ainda existe >> #p@p
Posted

Pois, não vi o código correctamente (por causa da indentação), mas ele deve estar a usar o gcc com as definições normais (sem avisos, com o standard gnu89).

Mas sei que tinhas dito que não era um erro; não estava a contrariar isso.

Quanto à unlink, o que eu queria dizer era que a remove() é que faz parte do standard 🙂

mastercgmr, como estás a compilar o código? lol

Posted (edited)

- conio.h : não existe (se bem que nem estou a ver porque estás a incluir isso)

- log10() : nem sei como compila no windows sem uma referência a esta função

- system() : já referiste

- remove() : é uma espécie de supra função para o unlink e o rmdir, se estás a apagar ficheiros usa diretamente o unlink

- remove_char() : não é um nome explítico do que a função realmente faz

- gets() : é uma função que deve ser evitada usando a sua substituta mais segura > fgets

- barra de progresso : existe maneira mais simples para apresentar isso sem essa matemática toda a baralhar

- indentação : não sei se foi por estás pouco habituado a fazer post de código, mas a indentação é inexistente

- c99 : eu compilo os meus projectos em c89 (sou piquinhas em relação a isso), logo não iria conseguir compilar (isto não é erro)

por alto será isto ...

HappyHippyHippo,

- conio.h: é parvoice não sei o que estava ali a fazer lol

- log10(): realmente não estou a entender como o compilador compila com esta função, voltei agora a testar e não tem problema... supostamente esta função está defendia em math.h http://www.cplusplus.com/reference/clibrary/cmath/log10/

-remove_char(): esta função tem a ver com o facto de quando se arrasta um ficheiro para a prompt, de forma a obter o seu caminho, se por ventura esse caminho tiver alguma pasta com espaços ele fica do genero "C:\Users\Carlos\Pasta teste\lol.txt" envolvido em aspas e o fopen da barraca se a sring tiver aspas

- gets() : já alterei 😉

- indentação: pois de facto não existe...já vou alterar

HHH,

Não há grande mal em usar-se C99, visto que o suporte para o mesmo já é decente nos compiladores mais utilizados. Não estive a ver com grande detalhe, mas pareceu-me que de C99 ele só utilizou os comentários //. O problema é grande parte das pessoas utilizarem sem saber tudo o que são extensões dos compiladores, isso concordo.

Quanto ao unlink, penso que essa só funciona em linux (é parte da unistd.h), mas corrige-me se estiver errado.

mastercgmr, além dos pontos já referidos pelo HHH, uma coisa que achei piada (alocar 0 elementos do tamanho de um char):

char *null;
null = (char *) calloc(0, sizeof(char)); //null é um carater com NULL

// e porque não assim?
char null = '\0';

Funciona exactamente da mesma forma, obrigado também já mudei!

Pois, não vi o código correctamente (por causa da indentação), mas ele deve estar a usar o gcc com as definições normais (sem avisos, com o standard gnu89).

Mas sei que tinhas dito que não era um erro; não estava a contrariar isso.

Quanto à unlink, o que eu queria dizer era que a remove() é que faz parte do standard 🙂

mastercgmr, como estás a compilar o código? lol

Para compilar estou a usar o Dev-C++ com o default complier fui ver ás opções, não sei se é o C99 mas julgo que seja.

#include <stdio.h>

int numdigits(int n){ //devolve o numero de digitos de um numero, ex 12345 = 5
return log10(n) + 1;
}

int calcmodulo(int numero_tamanho){//devolve 1 com um numero de zeros á frente igual ao de numero_tamanho
int modulo = 1;
while(numero_tamanho != 1){
	modulo = modulo * 10;
	numero_tamanho--;
	}
return modulo;
}

int getFileSize(FILE *input){	//dá o numero de bytes de um ficheiro
int fileSizeBytes;
fseek(input, 0, SEEK_END);
fileSizeBytes = ftell(input);
fseek(input, 0, SEEK_SET);
return fileSizeBytes;
}

void remove_aspas(char *string){ //função que remove primeiro e ultimo caracters de uma string
int idxToDel = 0;
memmove( &string[ idxToDel ] ,&string[ idxToDel+1 ], strlen(string) - idxToDel);
idxToDel = strlen(string)-1;
memmove( &string[ idxToDel ] ,&string[ idxToDel+1 ], strlen(string) - idxToDel);
}

int main() {
FILE *fp;
int i;
char file_name[500];
int modulo;
char null = '\0';

printf("\t\t\t|---------------------------------|\n");	
printf("\t\t\t|		   TotalDeleter		  |\n");
printf("\t\t\t|---------------------------------|\n");	
printf("\t\tThis program eliminates a file from memory permanently\n\n\n");
printf("The file path can not contain special characters.\n");
printf("Drag the file to this prompet:\nPath: ");

fgets(file_name);
printf("\n");

if(file_name[0] == '"')//caso o caminho esteja envolvido em aspas
	remove_aspas(file_name);

fp=fopen(file_name, "r+");

if (fp==NULL)
	perror ("The following error occurred");

long long int tamanho_ficheiro = getFileSize(fp);

if (tamanho_ficheiro == -1)
{
   printf("Invalid path!\n");
   system("pause");
   return 0;
}

printf("Size = %d bytes\n", tamanho_ficheiro);

printf("File open.\n");

printf("\n");

printf("Erase? ");

system("pause");

modulo = calcmodulo(numdigits(tamanho_ficheiro));
long long int cont = tamanho_ficheiro;

printf("0%%\n");

while(cont >= 0){
	fwrite(&null, sizeof(char), 1, fp);
	if(cont % modulo == 0 )
		printf("%d%%\n", 100-((cont*100)/tamanho_ficheiro)); //printa o loading do processo
		cont--;
}

fclose(fp);
printf("File overwritten.\n");
//system("pause");//PARA DAR TEMPO DE VERIFICAR SE O FICHEIRO FOI DEVIDAMENTE RESCRITO antes de acabar o programa
unlink(file_name);
printf("file deleted.\n");
system("pause");
return 0;
}
Edited by mastercgmr
Posted

podias ao menos compilar antes de apresentar o código ...

- log10() : mas tu nem estás a fzer include do <math.h> !!1

- remove_char() : eu sei o que a função faz porque estiva a interpretar o código desta, porque de outro modo não ia lá só pelo nome dela, é este ponto que referi > nome pouco ilucidativo

- fgets : http://www.cplusplus.com/reference/clibrary/cstdio/fgets/

- c99 : eu sei que compila em c99 pela simples razão que compila (antes destas alterações)

- unlink() : verifica os headers que necessitas, porque assim não vai compilar ...

IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

podias ao menos compilar antes de apresentar o código ...

- log10() : mas tu nem estás a fzer include do <math.h> !!1

- remove_char() : eu sei o que a função faz porque estiva a interpretar o código desta, porque de outro modo não ia lá só pelo nome dela, é este ponto que referi > nome pouco ilucidativo

- fgets : http://www.cplusplus.com/reference/clibrary/cstdio/fgets/

- c99 : eu sei que compila em c99 pela simples razão que compila (antes destas alterações)

- unlink() : verifica os headers que necessitas, porque assim não vai compilar ...

ora bem, de facto nao testei o codigo antes de o voltar a meter

no entanto só não estava a compilar por causa do fgets que teria de ficar algo do genro

fgets(file_name, sizeof(file_name) ,stdin)

no entanto isto apanha-me o \n no final da string e depois o fopen dá barraca, por isso optei por outra implemetação:

scanf ("%[^\n]", file_name).

De resto compila tudo sem warning nenhum... tanto o log10() como o unlink() também estou a achar isto esquisito... será alguma artimanha do Dev-C++?

Edited by mastercgmr
Posted

Hmmm ...

unlink() é POSIX, uma extensão ao Standard; remove() é uma função definida pelo Standard. Isto é: a primeira só funciona em implementações POSIX, a segunda funciona em todas as implementações de C existentes.

@mastercgmr:

para o teu programa precisas de especificar, pelo menos, mais o header <stdlib.h>.

a tua função remove_char() está a fazer duas cópias de memória, das quais só 1 é necessária.

"null" é um nome muito mal escolhido. Além disso, como já foi dito, esta variável nem devia ser um ponteiro. A minha sugestão é que uses 0 directamente.

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.