EnzoFerber
(usa FreeBSD)
Enviado em 27/05/2015 - 09:44h
Bom dia.
Vou colocar o código modificado pra você estudar. Todas as alterações que fiz estão nos comentário do código, assim fica fácil de você comparar o que você tinha feito com as modificações que fiz. Algumas coisas que tem que ser ditas:
1. Depois de usar
ftell com
SEEK_END, você necessariamente precisa rebubinar o arquivo. Para isso, existem duas formas:
rewind() ou
(void) fseek(stream, 0L, SEEK_SET).
De acordo com o manual (
http://linux.die.net/man/3/fseek), ambos os métodos são equivalentes.
2. Seu método de leitura do arquivo estava lendo o arquivo todo antes de fazer as comparações (você colocou
fgets() dentro de um
while() que só terminaria quando NULL fosse lido). Isso significa que quando saísse desse loop, sua string seria NULA.
3.
strcmp() não adianta, a menos que você coloque caracteres NULOS na string primária como forma de delimitação para fazer as comparações com a substring. Caso contrário, ele compara a primeira string em sua totalidade (o que não é o que você queria).
4. Coloquei dois métodos para achar uma substring:
for() +
strncmp() e
strstr().
Os manuais de todas as funções que usei:
rewind: http://linux.die.net/man/3/fseek
strncmp: http://linux.die.net/man/3/strncmp
strstr: http://linux.die.net/man/3/strstr
É interessante também olhar a
strcasestr(), que desconsidera o
case das letras (não diferencia maiúsculas de minúsculas). Está no mesmo manual da
strstr().
O
arq.txt que usei:
viva o linux
slackware e o melhor
patrick volkerding
linus torvalds
Jackson_Veiga
O código:
/* vol_forum/file.c
*
* Autor : Jackson_Veiga (VoL)
* Modificado por: Enzo Ferber
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* É boa prática declarar tamanhos de vetores como MACROS, assim, fica fácil
* alterar seus tamanhos caso você mude de idéia mais tarde.
*/
#define BUFFER 50
int main (void)
{
/* EDIT 1:
* Declarar todas as variáveis no inicio do escopo da função por
* motivos de clareza
*/
FILE *Input;
long tamanho;
char string1[BUFFER];
char string2[BUFFER];
char *s; /* s será o retorno de strstr() */
register int i;
if (!(Input = fopen("arq.txt","r"))) {
fputs ("\n\nErroa o abrir o arquivo\n\n",stderr);
//sai em caso de falha
exit (1);
}
fseek (Input ,0 , SEEK_END);
tamanho = ftell (Input);
// teste
printf("Quantidade de Caracteres= %ld\n",tamanho);
printf("Informe os caracteres a serem procurados: ");
fgets(string1, BUFFER, stdin);
/* O ultimo caractere no buffer string1 será '\n', trocamos por 0x0 */
string1 [strlen(string1) - 1] = 0x0;
printf("Caracteres Procurados: %s\n ",string1 );
/* EDIT 2:
* voltar o ponteiro do descritor do arquivo para o início do
* arquivo.
*/
rewind (Input);
printf("\n\nLeitura do arquivo\n");
// lê cada palavra do texto
while(!feof(Input)) {
/* EDIT 3:
* fgets() fora do outro while(), assim, ele lê a linha
* inteira, e te mostra o que foi lido. A comparação é feita
* depois.
*/
fgets(string2, BUFFER, Input);
printf("Valor lido: %s",string2);
/* EDIT 4:
* Você pode encontrar uma substring de duas formas:
* um loop for() e usar strncmp() ou utilizar a função
* strstr();
*/
/* EDIT 5:
* Antes, comparamos os tamanhos da string procurada (string1)
* com o tamanho da string lida (string2). Caso o tamanho da
* string 1 seja MAIOR QUE a string2, significa que ela
* não pode ser uma substring, então pulamos para a
* próxima leitura.
*/
if (strlen(string1) > strlen(string2)) continue;
/* MÉTODO 1: for() + strncmp()
*
* int strncmp(str1, str2, n)
* strncmp() irá comparar os 'n' primeiros bytes de str1 com
* os 'n' primeiros bytes de str2. No nosso caso, queremos
* comparar todos os bytes de str2, então utilizaremos a
* função strlen(str2) como argumento 'n'.
*/
for (i = 0; i < strlen(string2); i++) {
if (!strncmp(&string2[i], string1, strlen(string1) - 1 )) {
printf("Metodo STRCMP\n");
printf("Encontrado na linha: %s\n", string2);
printf("Posicao : %d\n\n", i);
}
}
/* MÉTODO 2: strstr()
* char *strstr(str1, str2)
*
* A função strstr() retorna um ponteiro para o início da
* ocorrência de str2 em str1 em caso de sucesso e um NULL
* em caso de falha.
*
* Esse método é bem mais facil de ser entendido.
*/
if ( (s = strstr(string2, string1)) ) {
printf("Metodo STRSTR\n");
printf("s: %s\n", s);
printf("Encontrado na posicao: %d\n", (int)(s - string2));
}
}
/* EDIT 6:
* É boa prática retornar um valor ao final de main(). Assim o programa
* informa que tudo terminou OK.
*/
return 0;
}
Espero ter ajudado,
Qualquer dúvida, posta denovo.
[]'s
Enzo Ferber
EDIT: Ah, quanto a limitação de 5 caracteres! Isso fica pra você fazer. Não é difícil não.
The generation of random numbers is too important to be left to chance.