Erro no código, e não consigo identificar o que é

1. Erro no código, e não consigo identificar o que é

João Victor Figueredo Fonseca
joaovfonseca

(usa Ubuntu)

Enviado em 17/02/2016 - 22:42h

Preciso fazer um mecanismo de pesquisa simples. Apenas abrir um arquivo.txt, procurar uma palavra desejada pelo usuário, verificar quantas vezes a palavra aparece no arquivo e se ela existe no arquivo. Porém esta dando um erro que não identifiquei a origem, semelhante a ausência do &. Segue meu código:
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#define max 500
int main(){
char pprocurada[100];
char *buff[500];
int contpp=0;
FILE *arq;
arq=fopen("C:\\Users\\jvict_000\\Desktop\\JoaoVictorF\\FaroesteCaboclo.txt", "r");
if(arq==NULL)
printf("n%co foi possivel abrir o arquivo\n",132);
printf("Digite a palavra a ser pesquisada\n");
fflush(stdin);
gets(pprocurada);
fflush(stdin);
fgets(*buff,max,arq);
while (!feof(arq)) {
if(contpp==0) {
strtok(*buff," ");
if(strcmp(pprocurada,*buff)==0)
contpp++;
} else {
strtok(NULL," ");
if(strcmp(pprocurada,*buff)==0)
contpp++;
}
fflush(stdin);
fgets(*buff,max,arq);
}
fclose(arq);
if(contpp!=0)
printf("Pesquisa terminada, a palavra %s foi encontrada: %d vezes",pprocurada,contpp);
else {
printf("A palavra %s n%co foi encontrada no arquivo",pprocurada,132);
}
return 0;
}



  


2. Re: Erro no código, e não consigo identificar o que é

Bruno Thomaz
SarusKant

(usa CentOS)

Enviado em 18/02/2016 - 10:58h

Segue abaixo o código corrigido.

#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#define max 500
int main(){
char pprocurada[100];
char buff[500];
int contpp=0;
FILE *arq;
arq=fopen("text", "r");
if(arq==NULL)
printf("n%co foi possivel abrir o arquivo\n",132);
printf("Digite a palavra a ser pesquisada\n");
fflush(stdin);
fgets(pprocurada,max,stdin);
while (!feof(arq)) {
fgets(buff,max,arq);
if(contpp==0) {
strtok(buff," ");
if(strcmp(pprocurada,buff)==0)
contpp++;
} else {
strtok(NULL," ");
if(strcmp(pprocurada,buff)==0)
contpp++;
}
fflush(stdin);
}
fclose(arq);
if(contpp!=0)
printf("Pesquisa terminada, a palavra %s foi encontrada: %d vezes",pprocurada,contpp);
else {
printf("A palavra %s n%co foi encontrada no arquivo",pprocurada,132);
}



3. Re: Erro no código, e não consigo identificar o que é

João Victor Figueredo Fonseca
joaovfonseca

(usa Ubuntu)

Enviado em 18/02/2016 - 19:06h

SarusKant escreveu:

Segue abaixo o código corrigido.

#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#define max 500
int main(){
char pprocurada[100];
char buff[500];
int contpp=0;
FILE *arq;
arq=fopen("text", "r");
if(arq==NULL)
printf("n%co foi possivel abrir o arquivo\n",132);
printf("Digite a palavra a ser pesquisada\n");
fflush(stdin);
fgets(pprocurada,max,stdin);
while (!feof(arq)) {
fgets(buff,max,arq);
if(contpp==0) {
strtok(buff," ");
if(strcmp(pprocurada,buff)==0)
contpp++;
} else {
strtok(NULL," ");
if(strcmp(pprocurada,buff)==0)
contpp++;
}
fflush(stdin);
}
fclose(arq);
if(contpp!=0)
printf("Pesquisa terminada, a palavra %s foi encontrada: %d vezes",pprocurada,contpp);
else {
printf("A palavra %s n%co foi encontrada no arquivo",pprocurada,132);
}


Não deu irmão, mesmo erro...


4. Diversos erros

Enzo de Brito Ferber
EnzoFerber

(usa FreeBSD)

Enviado em 19/02/2016 - 06:47h

Olá, bom dia.

Existem diversos erros no seu código, como a definição de buff, o uso de fflush em stdin, o uso de gets, o uso de strcmp com os parâmetros errados e a lógica da utilização da função strtok. Além de não pegar o retorno de strtok, você constantemente reseta o ponteiro de posição dela.

O manual: http://linux.die.net/man/3/strtok

Considere o seguinte programa (que é incorreto):


/* test.c
* Demonstracao do uso *incorreto* de STRTOK
*
* (C) 2016 - Enzo Ferber, <enzoferber@gmail.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
char *buf = malloc(100);
char *t;

strcpy(buf, "Programa mostrando o uso incorreto de strtok.");
while((t = strtok(buf, " ")))
printf("token: %s\n", t);

free(buf);
return 0;
}


Quando compilar e rodar, o programa irá ficar em um loop infinito, imprimindo token: Programa. A função strtok armazena internamente a posição onde parou a última análise. Porém, toda vez que o argumento é não nulo, ela redefine essa posição.

*


buf = Programa mostrando o uso incorreto de strtok.
pos = 0123456789...................................

Considere pos as posições dos caracteres na string. Agora chamamos:


t = strtok(buf, " ");


O mecanismo de strtok irá receber esse pointeiro e setar um ponteiro estático (static) para essa string. Depois, strtok irá encontrar o token que você delimitou. E o encontra na posição 8 de buf. (buf[8] == ' ')

O que strtok faz agora é:


1. coloca um caractere NULL na posicao buf[8] de maneira que você possa
manipular o token como um string normal.

2. atribui a posicao 9 ao ponteiro de referencia

3. Retorna o atual ponteiro de referencia


Todas essas informações podem ser deduzidas lendo o manual de strtok(3) em http://linux.die.net/man/3/strtok ou digitando man strtok no terminal.

Primeira chamada:

buf = Programa mostrando o uso incorreto de strtok.
pos = 0123456789...................................
| |- nova posicao
|
|- posicao atual
|- t

O problema é que uma segunda chamada a strtok utilizando o mesmo token que ele retornou vai retornar o primeiro token novamente! Como toda vez que você chama strtok com um argumento diferente de NULL ele reseta o ponteiro de posição, você termina analisando apenas o primeiro token da sua string (se todo o resto do código estivesse correto). Além do mais, a lógica por traz dos testes à contpp está incorreta. Pois após encontrar um token a primeira vez, o referido teste sempre será falso, o que resultará na avaliação apenas do bloco else para todas as outras linhas subsequentes: isto faz com que as outras linhas tenham referências completamente erradas dentro de strtok.

Resumindo, são tantos os erros que optei por postar um novo código. Para tentar demonstrar melhor o conceito por trás de strtok, o código analisa um arquivo palavra por palavra em um estilo parecido com strtok: utilizando armazenamento estático de posições. Ambas as funções next_word e next_line armazenam as referências de forma estática. A diferença com relação ao design de strtok é que essas funções só resetam as referências baseadas em uma condição interna, e não uma condição explícita nos parâmetros. Isto simplifica o uso sequencial e a API, porém custa flexibilidade. (Também é interessante notar que a função next_word entende por palavras apenas sequências de letras e números, qualquer coisa diferente é tratado como um delimitador e uma palavra é retornada.)


/* text.c
*
* (C) 2016 - Enzo Ferber, <enzoferber@gmail.com>
*/
#include <stdio.h> /* printf */
#include <stdlib.h> /* malloc */
#include <string.h> /* strncmp */
#include <ctype.h> /* isalnum */

#define LINE_MAX 500
#define WORD_MAX LINE_MAX

char *next_word(char *line)
{
static char *ref = NULL;
char *word = malloc(WORD_MAX);
char *w = word;

if(!word) return NULL;
if(!ref) ref = line;

while(*ref) {
if(isalnum(*ref)) {
*w++ = *ref++;
} else {
*w = 0x0;
ref++;
return word;
}
}

return (ref = NULL);
}

char *next_line(char *filepath)
{
static FILE *fp = NULL;
char *line;

if(!fp) {
if(!(fp = fopen(filepath, "r"))) {
perror("fopen");
return NULL;
}
}

/* fim de arquivo */
if(feof(fp)) {
fclose(fp);
return (char*)(fp = NULL);
}

/* buffer para linha */
if(!(line = malloc(LINE_MAX))) {
perror("malloc");
fclose(fp);
return (char*)(fp = NULL);
}

/* proxima linha */
if(!(fgets(line, LINE_MAX, fp))) {
fclose(fp);
free(line);
return (char*)(fp = NULL);
}

return line;
}

int main(int argc, char *argv[])
{
char *w, *line;
int count = 0;

if(argc < 3) return 0;

while((line = next_line(argv[1]))) {
while((w = next_word(line))) {
if(!strncmp(argv[2], w, LINE_MAX)) count++;
free(w);
}
free(line);
}

printf("%s encontrada %d vezes no arquivo %s.\n", argv[2], count, argv[1]);
return 0;
}



$ gcc -o text text.c -Wall -Wextra -Werror -pedantic --std=c11
$ ./text text.c char
char encontrada 16 vezes no arquivo text.c.
$


Espero ter ajudado,
Qualquer coisa posta denovo.

[]'s
Enzo Ferber


$ indent -kr -i8 src.c

"(...)all right-thinking people know that (a) K&R are _right_ and (b) K&R are right." - linux/Documentation/CodingStyle - TORVALDS, Linus.







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts