paulo1205
(usa Ubuntu)
Enviado em 10/04/2017 - 08:43h
mrroot escreveu:
#include <stdio.h>
#include <string.h>
int search_string(char texto[],char frase[]);
void limpa_string(char string[]);
Eu prefiro a notação de ponteiros como argumentos de função usando a forma geral de delcaração de ponteiros “
char *texto ”, em vez de “
char texto[] ”.
E a sua função
limpa_string deveria ter um segundo parâmetro, especificando o tamanho máximo que a string pode possuir.
O programa é em C ou em C++? Se for em C, deveria haver a palavra-chave
void entre os parênteses, de modo a indicar que
main () não vai receber argumentos. Com os parênteses vazios, o significado em C é que
main () pode receber uma quantidade qualquer de argumentos de quaisquer tipos.
{
//int p;
char texto[100];
char frase[100];
printf("Digite um texto:");
scanf("%[^\n]s",texto);
Sua string de formatação está errada. Aquele “
s ” após o fechamento de colchetes está sobrando, e na prática faz com que a função interrompa a execução antes de chegar ao final da string de formatação.
Você possivelmente pensou que os colchetes e a expressão dentro deles são modificadores da conversão
"%s" , mas não é assim que a coisa funciona. A conversão
"%[" é uma conversão de seu próprio direito, distinta de
"%s" e com regras de funcionamento diferentes.
Além do mais, conviria a você testar o valor de retorno de
scanf () (algumas implementações exigem que você faça isso; o Ubuntu, por exemplo, o faz), bem como colocar limites na quantidade de caracteres que a conversão pode colocar na string. Como
texto é um array com espaço para cem caracteres, eis como você poderia fazer.
int a, b, c, r;
/* ... */
/* Prepara leitura. */
a=b=c=0;
/*
Lê, descartando espaços no início da linha, limitando a largura do
texto a 100 caracteres (99 de texto, mais um para o terminador),
e tenta encontrar e consumir o terminador de linha (o que dispensa
o uso que você fez de getchar(), mais abaixo). Guarda as quanti-
dades de caracteres consumidos antes do texto, entre o fim do
texto e a tentativa de consumir o fim de linha e após o suposto
consumo desse fim de linha, respectivamente, em ‘a’, ‘b’ e ‘c’,
para ajudar a ver se a linha está de acordo com o formato
esperado.
*/
r=scanf(" %n%99[^\n]%n%*1[\n]%n", &a, texto, &b, &c);
/* Valida a leitura. */
if(r!=1 || b<=a || c<=b){
/*
Se r!=1, a conversão falhou. Se b<=a, o texto é vazio (caso que
eu considero inválido, até porque não deveria ocorrer, especial-
mente com o descarte de espaços no início da linha). Se c<=b,
então faltou o fim de linha, o que pode ser indicativo de que o
texto excedeu 99 caracteres (fácil de testar, verificando quanto
é o valor de b-a) ou que ocorreu alguma exceção, como erro de
leitura ou fim de arquivo.
Em todo caso, se você cair aqui, ou o valor de texto é inválido,
ou o buffer de entrada vai estar num estado inconsistente para
uma próxima operação de leitura. Você deve dar um tratamento
de erro adequando, em vez de simplesmente seguir com a exe-
cução do programa.
*/
/* COLOQUE SEU TRATAMENTO DE ERRO AQUI. */
}
/* Neste ponto, ‘texto’ deve conter um texto válido. */
getchar();
printf("Digite uma frase:");
scanf("%[^\n]s",frase);
Mesmo comentário sobre o uso equivocado de
scanf ().
search_string(texto,frase);
}
int search_string(char texto[],char frase[])
{
int i,j; //variavel de loop
int aux; // armazena a posição de i caso a posição de i combine com a frase na posição 0
char teste[strlen(frase)];
Eu GARANTO a você que você não vai precisar de um terceiro array. Mesmo que precisasse, você deveria alocar espaço para
strlen(frase)+1 caracteres, pois o terminador da string tem de ser considerado como parte do vetor que contém a string.
char c;
int x;
int p = 0;
limpa_string(teste);
Você deveria usar um outro argumento para indicar o tamanho da área de dados a ser limpa.
for(i=1;i<=strlen(texto)-strlen(frase);i++)
Grande chance de erro aí. Lembre-se que, em C, os índices de vetores sempre começam a ser contados de zero, não de 1. Em outras palavras, um vetor com
N elementos tem índices que vão de
0 até
N-1 . Você parece estar querendo ir de
1 até
N , e estará errando se o fizer.
{
if(texto[i ]==frase[1])
{
aux = i;
for(j=1;j<=strlen(frase);j++)
Mesmo problema com índices fora da faixa, com o agravante de que você não reservou espaço para o terminador em
teste . Como você efetua a cópia do terminador (ainda que o faça sem querer!), copia-o para uma posição inválida no array de destino. Sabe-se lá o que existirá nessa posição inválida -- pode ser outra variável, algum dado de controle, um endereço de retorno da função, ou mesmo uma posição de memória inválida, que faça o programa capotar quando a ela se faz acesso.
{
c = texto[aux];
teste[j] = c;
aux++;
}
}
x = strcmp(teste,frase);
Note o desperdício: você mal acabou de varrer todo o array
frase , comparando-o com
texto , e agora faz outra varredura de comparação! Não lhe soa isso como um sinal de que a segunda comparação é redundante (desde que você embuta algumas partes faltando junto à primeira comparação)?
limpa_string(teste);
if(x==0)
{
p = p + 1;
Você quer saber onde no texto se localiza a frase ou quantas vezes a frase acontece dentro do texto? Parece que você acabou tentando implementar a segunda opção.
Você disse que a função retorna um valor inteiro. Onde está o comando que efetivamente faz esse valor inteiro ser retornado?
}
void limpa_string(char string[])
Já disse acima que esta função deveria ter dois parâmetros, com um deles informando o tamanho da área a ser limpada.
{
int i = 0;
while(i<strlen(string))
Qual você espera que seja o valor retornado por
strlen(string) ? Acha que ele tem alguma relação com o tamanho do array onde a string está contida?
Se acha, saiba que não tem. Você não tem sequer qualquer garantia de que o ponteiro passado como argumento é válido ou que aponte para uma string (i.e. que exista pelo menos um caráter nulo dentro do espaço apontado, dentro dos limites do vetor original). Eis outra razão pela qual seria necessário ter outro parâmetro, informando o tamanho a ser limpado, mesmo que o vetor originalmente não possa ser usado com
strlen ().
{
string[i] = '\0';
i++;
}
}