Jump to content
LegaliZe

Dividir um string em N caracteres

Recommended Posts

LegaliZe

Boas, tenho um programa para fazer mas não tou a conseguir dividir a string, o objectivo é dada a string: "abacadbacabacac" ou outra introduzida pelo utilizador e um valor entre 0 e 10 dar a palavra que se repete mais vezes com esse valor de caracteres neste caso se assumir-mos o valor 3 na string abacadbacabacac sera a palavra "aca". mas a duvido ke tenho e saber como posso dividir a string em varias com 3 caracteres cada ou seja

aba

bac

aca

cad

adb

dba

bac

aca

cab

aba

bac

aca

cac

isto vai variar caso o N seja 4 ou outro valor qualquer. Penso ter explicado bem a situação, agora gostaria de saber como posso repartir assim uma string em varias.

Share this post


Link to post
Share on other sites
Localhost

Supondo que lês um número inteiro N tens que fazer um ciclo de 0 até ao fim da string e aumentar a variável que utilizas para o ciclo de N em N. Se quiseres, em cada passo no ciclo podes meter a substring num vector de strings (utilizando a função strncpy).


here since 2009

Share this post


Link to post
Share on other sites
LegaliZe

ou seja do genero?

 for (i=0;s[i]!='\0';i+=n) 

então mas apartir daqui como faco pa dividir em substrings?

Share this post


Link to post
Share on other sites
Localhost

Sim, é isso.

Agora para dividires em substrings terias um vector de strings. Depois a cada passo no ciclo copiavas para a posição adequada (avançar de 1 em 1) com a função strncpy a substring.

Vou-te dar um exemplo porque acho que já percebeste a ideia disto.

for (k = 0, i = 0; str[k]; k += N, i++)
   strncpy (my_strings[i], &input_string[k], N); 


here since 2009

Share this post


Link to post
Share on other sites
LegaliZe

Já testei e n consegui listar como strings apenas como caracteres ou seja deu isto, o que não é bem o que quero mas o problema é tar em %c por que se meto %s o programa deixa de responder:

2j3k7sy.jpg

char matriz(char s[20], int n)
{
     int i,k,len;
     //len=strlen(s);
     for (k = 0, i = 0; s[i]; k++, i++)
         {
            printf( "%c\n" , s[k] );
          //strncpy ( &s[i] , &s[k] , n); como é com caracteres a funcão n ta a funcionar, e senão por & 
                                                      //em ambas da-me warning   de pointer para integer without a cast
            printf( "%c", s[i] ); 
          }     
}

Share this post


Link to post
Share on other sites
Baderous

Supondo que lês um número inteiro N tens que fazer um ciclo de 0 até ao fim da string e aumentar a variável que utilizas para o ciclo de N em N. Se quiseres, em cada passo no ciclo podes meter a substring num vector de strings (utilizando a função strncpy).

Acho que interpretaste mal o problema. Ele não quer partir a string em fatias, ele quer percorrer a string, e para cada posição gerar a substring iniciada nessa posição e com tamanho N. Portanto, seguindo a tua sugestão de usar a função strncpy, é necessário alocar primeiramente o array das substrings para depois as copiar para lá uma a uma. Não esquecer que a string não é percorrida até ao fim, o algoritmo pára quando já não der para criar uma substring de tamanho N a partir da posição em que nos encontramos:

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

int main(void) {
        char str[] = "abacadbacabacac";
        char** aux = NULL;
        int i, n, len, size;
        len = strlen(str);
        printf("Introduza o valor: ");
        scanf("%d",&n);
        size = len-n+1;
        aux = (char**)malloc(sizeof(char*)*size);
        for (i=0;i<len-n+1;i++) {
                aux[i] = (char*)malloc(sizeof(char)*n);
                strncpy(aux[i],&str[i],n);
        }
        for (i=0;i<size;i++)
                printf("%s\n",aux[i]);
        for (i=0;i<size;i++)
                free(aux[i]);
        free(aux);
        return 0;
}

Introduza o valor: 3
aba
bac
aca
cad
adb
dba
bac
aca
cab
aba
bac
aca
cac

Share this post


Link to post
Share on other sites
LegaliZe

Sim o objectivo não é partir strings, mas pensei que fosse mais facil contar as vezes que aquele bocado de string se repete se tiver repartida. Vou dar uma vista de olhos nesse codigo ah e obrigado pela dica com a memoria dinamica, porque vou ter de aplicar memoria dinamica no programa mas tava primeiro a tentar resolver o problema com memoria estática

EDIT: Testei o programa e ta a fazer o que eu queria mas apenas para numeros impares, ao introduzir qualquer numero par ele adiciona sempre lixo no output provavelmente sera por causa da reserva de memoria.

Fixed: o problema estava mesmo na memoria, a minha solucao foi usar o calloc no segundo malloc para inicializar os valores todos a 0.

for (i=0;i<size;i++) {
                aux[i] = (char*)calloc(size,sizeof(char)*n);
                 if (aux[i]==NULL)
                    {
                      printf("Erro na reserva de memória\n");
                      exit(1);
                    } 
                strncpy(aux[i],&str[i],n);
                
        }

Share this post


Link to post
Share on other sites
Localhost

Baderous: Não entendo por que razão se tem de alocar o vector de strings dinamicamente.


here since 2009

Share this post


Link to post
Share on other sites
Baderous

Aloquei dinamicamente porque o tamanho dependia do tamanho da string fornecida (neste caso está hard-coded mas podia vir de um ficheiro, por exemplo). Podia-se dar um tamanho inicial X e depois, caso não fosse suficiente, alocava-se dinamicamente mais espaço. Também se podia usar um VLA, mas como supus que a cadeia de caracteres iria ser grande, tornava-se perigoso.

Share this post


Link to post
Share on other sites
LegaliZe

consegui resolver o problema mas agora tenho outro  :wallbash: o problema agora é que não consigo submete-lo na plataforma UVa da sempre Runtime Error apesar de ele correr perfeitamente quando compilado tanto no DEV C como em Linux deixo aqui o codigo caso descubram algo que eu não vi e tambem o erro que recebo no mail:

Your submission with number 8806929 for the problem 902 - Password Search has failed with verdict Runtime error.

This means that the execution of your program didn't finish properly. Remember to always terminate your code with the exit code 0.

Best regards,

The UVa Online Judge team

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

int main() {
        char str[50];
        char** aux = NULL;
	char** aux2 = NULL; 
        int i,j, n, len, size,cont,ax1=0,ax2=0;
        
        printf("Introduza o valor: ");
        scanf("%d",&n);
        printf("Introduza a frase :");
        scanf("%s",str);
        
        len = strlen(str);
        size = len-n+1;
        aux = (char**)malloc(sizeof(char*)*size);
        if (aux==NULL)
           {
            printf("Erro na reserva de memoria\n");
            exit(1);
            }
        aux2 = (char**)malloc(sizeof(char*)*size);
        if (aux==NULL)
           {
            printf("Erro na reserva de memoria\n");
            exit(1);
            }
        for (i=0;i<len-n+1;i++) 
            {
                aux[i] = (char*)calloc(size,sizeof(char)*n);
                if (aux==NULL)
                   {
                    printf("Erro na reserva de memoria\n");
                    exit(1);
                   }
                strncpy(aux[i],&str[i],n);
                aux2[i] = (char*)calloc(size,sizeof(char)*n);
                if (aux==NULL)
                   {
                    printf("Erro na reserva de memoria\n");
                    exit(1);
                    }
                strncpy(aux2[i],&str[i],n);       
            }

        for (i=0;i<size;i++)
            {
             cont=0;
             for(j=0;j<size;j++)
                  {
		if(i!=j)
                        {
		    if(strcmp(aux[i],aux2[j])==0)
			  {
				cont++;
                             if(cont>ax1)
				 {
				    ax1=cont;
				    ax2=i;
				  }					 				
			   }

                          }
                    }
            }
       
         
       	if(ax1==0)
       		{
       			printf("Palavra pass nao encontrada, nao existem repeticoes na frase\n");
       			
		   for (i=0;i<size;i++)
         		{
                 free(aux[i]);
                 free(aux2[i]);
         		}
               free(aux2);
               free(aux);
  	       return 0;
       		}
       	else
       	
        	printf("%s\n",aux[ax2]);
        
         	for (i=0;i<size;i++)
      		{
                free(aux[i]);
                free(aux2[i]);
        	 }
            free(aux2);
            free(aux);
            return 0;
}

Share this post


Link to post
Share on other sites
falk0n


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

int main() {
        char str[50];
        char** aux = NULL;
                char** aux2 = NULL;
        int i,j, n, len, size,cont,ax1=0,ax2=0;
       
        printf("Introduza o valor: ");
        scanf("%d",&n);
        printf("Introduza a frase :");
        scanf("%s",str);
       
        len = strlen(str);
        size = len-n+1;
        aux = (char**)malloc(sizeof(char*)*size);
        if (aux==NULL)
           {
            printf("Erro na reserva de memoria\n");
            exit(1);
            }
        aux2 = (char**)malloc(sizeof(char*)*size);
        if (aux==NULL)
           {
            printf("Erro na reserva de memoria\n");
            exit(1);
            }
        for (i=0;i<len-n+1;i++)
            {
                aux[i] = (char*)calloc(size,sizeof(char)*n);
                if (aux==NULL)
                   {
                    printf("Erro na reserva de memoria\n");
                    exit(1); // na outra parte utilizas return aqui utilizas exit ? pq ? 
                   }
                strncpy(aux[i],&str[i],n);
                aux2[i] = (char*)calloc(size,sizeof(char)*n);
                if (aux==NULL) // este não sera aux2 ? em vez de aux ? cuidado com os callocs 
                   {
                    printf("Erro na reserva de memoria\n");
                    exit(1);
                    }
                strncpy(aux2[i],&str[i],n);      // para que lhe estas a dar o endereço do endereço ? sendo um array ja lhe estas a dar um endereço
            }

        for (i=0;i<size;i++)
            {
             cont=0;
             for(j=0;j<size;j++)
                  {
                        if(i!=j)
                        {
                            if(strcmp(aux[i],aux2[j])==0)
                                  {
                                        cont++;
                                     if(cont>ax1)
                                         {
                                            ax1=cont;
                                            ax2=i;
                                          }                                                                    
                                   }
                                               
                          }
                    }
            }
       
         
        if(ax1==0)
                {
                        printf("Palavra pass nao encontrada, nao existem repeticoes na frase\n");
                       
                           for (i=0;i<size;i++)
                        {
                 free(aux[i]);
                 free(aux2[i]);
                        }
               free(aux2);
               free(aux);
               return 0;
                }
        else
       
                printf("%s\n",aux[ax2]);
       
                for (i=0;i<size;i++)
                {
                free(aux[i]);
                free(aux2[i]);
                 }
            free(aux2);
            free(aux);
            return 0;
}

Porque é que estas a utilizar calloc em vez de malloc nessas funcoes ?

Pode não ser nada mas acho que poderias rever um pouco o teu codigo com base em algo que idiquei. Pode continuar a funcionar mas acho que deverias rever o pq de algumas coisas para ser mais consistente ou dar uma explicação do pq de usar umas em vez de outras.

Boas programações

Share this post


Link to post
Share on other sites
LegaliZe

tinha posto o calloc porque ele tava a dar-me lixo sempre que inseri-se um valor par no N, entao experimentei usar o calloc pa por os valores a zero, mas ah uma funcao pa fazer isso tambem o memset mas n sei trabalhar com ele.

strncpy(aux2[i],&str[i],n);      // para que lhe estas a dar o endereço do endereço ? sendo um array ja lhe estas a dar um endereço

penso que a propria funcao precisa do & mas nao tenho a certeza

Share this post


Link to post
Share on other sites
falk0n

ok, sim nisso tens razão pode acontecer, ele não coloca a zeros as posições de memória.

      The strncpy() function is similar, except that at most n bytes of src are copied.  Warning: If there is no null byte among the  first  n  bytes  of

      src, the string placed in dest will not be null-terminated.

      If the length of src is less than n, strncpy() pads the remainder of dest with null bytes.

      A simple implementation of strncpy() might be:

         

char*
           strncpy(char *dest, const char *src, size_t n){
               size_t i;

               for (i = 0 ; i < n && src[i] != '\0' ; i++)
                   dest[i] = src[i];
               for ( ; i < n ; i++)
                   dest[i] = '\0';

               return dest;
           }

From strncpy man page .

Acho que o teu problema possa estar aqui, na utilização do strncpy quando lhe passas o endereço do array ... ou posso estar enganado pois nem corri o programa.

Também verifica se no if onde tens aux == NULL não queres dizer aux2 == NULL ...

Boas programações

Share this post


Link to post
Share on other sites
Localhost

@LegaliZe: para a próxima deixa o link do problema que estás a resolver para ser mais fácil perceber o teu próprio problema.

Neste problema em específico não necessitas de matriz nenhuma. Só precisas da string de input e de dois ciclos.

Começas com um ciclo que vai percorrer do início até ao fim de um em um. No inner-loop (j) vais percorrer desde a posição do primeiro ciclo (i) até ao fim da string e vais comparando (utilizando a função strncmp e strncpy) a substring do primeiro ciclo com a do segundo. A cada match bem sucedido incrementas um contador. No final guardas o resultado óptimo.


here since 2009

Share this post


Link to post
Share on other sites
LegaliZe

Também verifica se no if onde tens aux == NULL não queres dizer aux2 == NULL ...

Boas programações

:x sim é aux2 vou alterar e ver se era por isso.

E eu a complicar as coisas xD mas ele tambem devia aceita-lo assim  penso eu, pode é demorar mais tempo a correr

Share this post


Link to post
Share on other sites
falk0n

e experimenta a retirar o & do str[ ? ] no strncpy .

Boas programações

Share this post


Link to post
Share on other sites
falk0n

Desculpa, não percebi a tua resposta. O programa deixa de funcionar ? é isso ?

Boas programações.

Share this post


Link to post
Share on other sites
LegaliZe

no caso do DEV C deixa de responder a janela onde corre o programa

Share this post


Link to post
Share on other sites
falk0n

Ok, e estás a verificar os tamanhos de size len e afins, será que algum é negativo ou zero ?

Podes fornecer os dados de input que estas a dar para poder testar o teu código ?

Boas programações

Share this post


Link to post
Share on other sites

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.