Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: ZedGe en 2 Abril 2013, 17:47 pm



Título: Ayuda con código para re ordenar array
Publicado por: ZedGe en 2 Abril 2013, 17:47 pm
Lo que necesito es que dado un array de largo 80, cree otro que re ordene los datos del anterior según la clase de los datos.

En otras palabras, entra un código de letras y numero, y necesito que en el nuevo arreglo, en cada casilla se guarden los números y letras por separado según se lean.

Adjunto una imagen para que me entiendan mejor, el primero es el código que entra, y lo de abajo es como necesito que quede el otro arreglo.

(http://i1113.photobucket.com/albums/k503/ZedGe1505/asd12_zpscb7034d1.png)


Este es el código erróneo que tengo hasta ahora:


Código:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <string.h>


using namespace std;


char* organizar(char *operacion);

int main()
{
    char dato_entrada[80];
    cout << "Ingrese Codigo: ";
    cin  >> dato_entrada;
    char* operacion = organizar(dato_entrada);
    printf(operacion);
    return 0;
}


char* organizar (char* operacion){

int largo=0;  //largo total
int largo2=0; //recorre aux2
int largo3=0; //recorre el codigo inicial
while (operacion[largo]!='\0') largo++;//cuenta el largo del codigo

char* aux2 = '\0'; //array que tendra la separaciones

while(largo3 < largo){

if(operacion[largo3] != '0' || operacion[largo3] != '1' || operacion[largo3] != '2'){
aux2[largo2] = strcpy(aux2[largo2],operacion[largo3]); //si encuentra un 0 1 o 2 lo guarda
printf(aux2[largo2]);
largo3++;
}

else if (operacion[largo3] != 'a' || operacion[largo3] != 'b' || operacion[largo3] != 'c'){
aux2[largo2] = strcpy(aux2[largo2],&operacion[largo3]); //si encuentra un a b o c lo guarda
printf(aux2[largo2]);
largo3++;
}

else largo2++;

}

return aux2;
}


Título: Re: Ayuda con código para re ordenar array
Publicado por: Wofo en 2 Abril 2013, 20:16 pm
No he leído tu código, pero has incluido "stdio.h" dos veces.


Título: Re: Ayuda con código para re ordenar array
Publicado por: Puntoinfinito en 2 Abril 2013, 21:03 pm
Más fácil todavía. Primero miras el tamaño de la char, todo y que sabemos su tamaño.

Código:
dato_entrada.size();

Ahora con un ciclo vas mirando una por una diciendo si es letra o número;

Código:
... !variable > Z ...

Esto lo verifica, entonces haces que vaya almacenando contenido a una misma posición que ya iras controlando con una variable y con append vas añadiendo, y en caso de que esto cambie (haces un else puro y duro) lo vaya almacenando a la siguiente posición y vaya ordenándolo. Y listo.


Título: Re: Ayuda con código para re ordenar array
Publicado por: ZedGe en 2 Abril 2013, 23:27 pm

Esto lo verifica, entonces haces que vaya almacenando contenido a una misma posición que ya iras controlando con una variable y con append vas añadiendo, y en caso de que esto cambie (haces un else puro y duro) lo vaya almacenando a la siguiente posición y vaya ordenándolo. Y listo.

use el append pero me da problemas al querer trabajar con char* :/


Título: Re: Ayuda con código para re ordenar array
Publicado por: Puntoinfinito en 3 Abril 2013, 16:26 pm
Si muestras parte del código te puedo ayudar mucho mejor ;)

Ahora que caigo append es un parametro de la librería string, pero de todas maneras creo que se puede utilizar con char. La utilización tendría que ser;
Código
  1. char variable[4] = {'H', 'o','l'}; //creamos una sequencia char con un espacio libre
  2. append(variable[3],'a'); //lo rellenamos

Esto recuerda que se puede hacer de manera automática;

Código
  1. for (int i = 0;i<variable.size();i++) {
  2. append(variable[i],'loquesea');
  3. }
  4.  

Si continuas teniendo error, utiliza strcpy, que es el que utilizaba yo;

Código
  1. char a[12] = "World";       /*  12 = strlen("Hello World") + 1  */
  2. strcpy(a, "Hello World");

Saludos!!  :D


Título: Re: Ayuda con código para re ordenar array
Publicado por: ZedGe en 3 Abril 2013, 23:41 pm
Me sigue dando errores al usar append o strcpy,que no puedo pasar de char a const char, o derrepente sale de char a char*


Título: Re: Ayuda con código para re ordenar array
Publicado por: 85 en 4 Abril 2013, 02:40 am
El tema de const char* a char* o vice versa, es un tema de 'casting', se soluciona haciendo casting y listo, puesto que 'const' es tan sólo una protección del compilador a nivel código, para el programador, para que se remarquen que ciertas "cosas" son constantes. Y Siendo así, deberías o bien respetar esto o bien saber muy bien por qué habrías de cambiarlo..


Título: Re: Ayuda con código para re ordenar array
Publicado por: Puntoinfinito en 4 Abril 2013, 15:03 pm
Sube código


Título: Re: Ayuda con código para re ordenar array
Publicado por: ZedGe en 4 Abril 2013, 17:11 pm
El codigo es ese que subi en el post :S


Título: Re: Ayuda con código para re ordenar array
Publicado por: 85 en 4 Abril 2013, 18:39 pm
Si se trata de escribir una cadena alfanumérica y hacer que la misma se divida en bloques separados de letras o números, entonces en ese caso escribí un código simple que hace eso, el tema es que justo me dieron ganas de no hacer nada XD y lo dejé funcionando pero sin terminar ya que no llegué a implementar memoria dinámica para que quede terminado.
En lugar de eso existe un array de cadenas de un máximo aceptable de 20 cadenas, pero para ver como se hace te va a servir.
Tu código dijiste que estaba mal por eso te muestro este otro código.

Como te dije, está sin terminar pero por eso mismo si te interesa lo podés terminar, implementando memoria dinámica para el array de cadenas que vas a usar para guardar todos los bloques.

Código
  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. #include<string.h>
  4. //http://www.cplusplus.com/reference/cstdlib/realloc/
  5.  
  6.  
  7. int main(){
  8.  
  9.  
  10. char cadena[512];
  11. //char** array_de_cadenas_r = 0;
  12. //char** array_de_cadenas = (char**)malloc(sizeof(char)*1);
  13. //array_de_cadenas[0] = (char*)malloc(sizeof(char)*128);
  14.  
  15. char array_de_cadenas[20][128] = {{0}};
  16.  
  17. printf("ingrese la cadena..\n");
  18. scanf("%s", cadena);
  19.  
  20. int modo=0;
  21. int pos=-1;
  22. int let;
  23. int num;
  24. int i=0;
  25. int j;
  26. while(cadena[i]){
  27.  
  28. if(pos == 20) break;
  29.  
  30. if(cadena[i] >= 'a' && cadena[i]<='z'){
  31. let++;
  32. num=0;
  33. }
  34. else if(cadena[i] >= 'A' && cadena[i]<='Z'){
  35. let++;
  36. num=0;
  37. }
  38. else if(cadena[i] >= '0' && cadena[i]<='9'){
  39. num++;
  40. let=0;
  41. }
  42. else
  43. {
  44. let=0;
  45. num=0;
  46. }
  47.  
  48. if((modo==1&&let)||(modo==2&&num));
  49. else
  50. {
  51. pos++;
  52. j=0;
  53.  
  54. //int a=0;
  55. //char backup[512];
  56. //strcpy(backup, array_de_cadenas[a]);
  57. //array_de_cadenas_r = (char**)realloc(array_de_cadenas, sizeof(char)*(pos+1));
  58. //array_de_cadenas[pos] = (char*)malloc(sizeof(char)*128);
  59. }
  60.  
  61.  
  62. if(let){
  63.  
  64. array_de_cadenas[pos][j] = cadena[i];
  65. j++;
  66. modo=1;
  67. }
  68. else if(num){
  69.  
  70. array_de_cadenas[pos][j] = cadena[i];
  71. j++;
  72. modo=2;
  73. }
  74. else
  75. {
  76. modo=0;
  77. }
  78.  
  79. i++;
  80. }
  81.  
  82. for(int b=0; b<pos+1; b++){
  83.      printf(array_de_cadenas[b]);
  84.      putchar('\n');
  85. }
  86.  
  87. //for(int c=0; c<pos; c++) free(array_de_cadenas[c]);
  88. //free(array_de_cadenas);
  89.  
  90. system("pause");
  91. return 0;
  92. }
  93.  


Título: Re: Ayuda con código para re ordenar array
Publicado por: ZedGe en 4 Abril 2013, 19:22 pm
gracias amigo lo adaptare a lo otro que necesito :P muchas gracias....

pero podrías explicarme algo??


Citar
if((modo==1&&let)||(modo==2&&num));
      else
      {
         pos++;
         j=0;
      }

para que es esa parte del codigo?


Título: Re: Ayuda con código para re ordenar array
Publicado por: 85 en 5 Abril 2013, 00:50 am
Ak está el code, avisenme cualquier koza si algún detaye se habrá escapado XD

Eso que remarcastes significa lo siguiente, son todos los casos en los cuales se continúa copiando char por char hasta completar un bloque.
un bloque se forma o sólo por letras o sólo por números.
Entonces esa comprobación comprueba el estado de un par de flags o agrupación de flags, que informan el paso de un bloque a otro, o mejor dicho el final de un bloque.
Si se encuentra ante el final de un bloque, entonces se incrementa la posición en el array dinámico,  y se resetea el contador usado para copiar cadenas.

Código
  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. #include<string.h>
  4. //http://www.cplusplus.com/reference/cstdlib/realloc/
  5.  
  6.  
  7. int main(){
  8.  
  9.  
  10. char cadena[512];
  11. char** array_de_cadenas = 0;
  12. char** array_de_cadenas_r = (char**)malloc(sizeof(char)*1);
  13. array_de_cadenas_r[0] = (char*)malloc(sizeof(char)*128);
  14. memset(array_de_cadenas_r[0],0,sizeof(char)*128);
  15.  
  16. // char array_de_cadenas[20][128] = {{0}};
  17.  
  18. printf("ingrese la cadena..\n");
  19. scanf("%s", cadena);
  20.  
  21. int modo=0;
  22. int pos=-1;
  23. int let=0;// contador usado como flag
  24. int num=0;// contador usado como flag
  25. int i=0;
  26. int j=0;
  27. while(cadena[i]){
  28.  
  29. //if(pos == 20) break;
  30. if(j==(128-2)) {
  31.  
  32. printf("uno de los bloques sobrepasa char=128-2\n");
  33. system("pause");
  34. return 0;
  35. }
  36. if(cadena[i] >= 'a' && cadena[i]<='z'){
  37. let++;
  38. num=0;
  39. }
  40. else if(cadena[i] >= 'A' && cadena[i]<='Z'){
  41. let++;
  42. num=0;
  43. }
  44. else if(cadena[i] >= '0' && cadena[i]<='9'){
  45. num++;
  46. let=0;
  47. }
  48. else
  49. {
  50. let=0;
  51. num=0;
  52. }
  53.  
  54. if((modo==1&&let)||(modo==2&&num));
  55. else
  56. {
  57. pos++;
  58. j=0;
  59. array_de_cadenas_r = (char**)realloc(array_de_cadenas_r, sizeof(char)*(pos+1));
  60. array_de_cadenas_r[pos] = (char*)malloc(sizeof(char)*128);
  61. memset(array_de_cadenas_r[pos],0,sizeof(char)*128);
  62. }
  63.  
  64.  
  65. if(let){
  66.  
  67. array_de_cadenas_r[pos][j] = cadena[i];
  68. j++;
  69. modo=1;
  70. }
  71. else if(num){
  72.  
  73. array_de_cadenas_r[pos][j] = cadena[i];
  74. j++;
  75. modo=2;
  76. }
  77. else
  78. {
  79. modo=0;
  80. }
  81.  
  82. i++;
  83. }
  84.  
  85. array_de_cadenas = array_de_cadenas_r;
  86. for(int b=0; b<pos+1; b++){
  87. printf(array_de_cadenas[b]);
  88. putchar('\n');
  89. }
  90.  
  91. for(int c=0; c<pos; c++) free(array_de_cadenas[c]);
  92. free(array_de_cadenas);
  93.  
  94. system("pause");
  95. return 0;
  96. }
  97.  




Título: Re: Ayuda con código para re ordenar array
Publicado por: rir3760 en 5 Abril 2013, 04:03 am
Si se trata de escribir una cadena alfanumérica y hacer que la misma se divida en bloques separados de letras o números
En C otra forma de realizar esa operación es mediante las funciones isdigit e isalpha mas punteros a funciones, estos para alternar entre los sets a procesar (digitos ==> alfabeticos ==> digitos ...).

Si ignoramos por un momento la validación de errores de malloc y realloc, un ejemplo de ello es:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. char **separar(char *p);
  5.  
  6. int main(void)
  7. {
  8.   char **mat;
  9.   int i;
  10.  
  11.   mat = separar("01ab210c");
  12.  
  13.   for (i = 0; mat[i] != NULL; i++){
  14.      printf("%2d: %3s\n", i, mat[i]);
  15.      free(mat[i]);
  16.   }
  17.   free(mat);
  18.  
  19.   return EXIT_SUCCESS;
  20. }
  21.  
  22. #include <string.h>
  23. #include <ctype.h>
  24.  
  25. char **separar(char *p)
  26. {
  27.   int (*pfn[2])(int) = {isdigit, isalpha};
  28.   int set;
  29.  
  30.   char **mat;
  31.   int i;
  32.   char *q;
  33.  
  34.   mat = malloc((strlen(p) + 1) * sizeof *mat);
  35.   i = 0;
  36.   set = isalpha(*p) != 0;
  37.  
  38.   while (pfn[set](*p)){
  39.      for (q = p + 1; pfn[set](*q); q++)
  40.         ;
  41.  
  42.      mat[i] = malloc(q - p + 1);
  43.      sprintf(mat[i], "%.*s", (int) (q - p), p);
  44.      i++;
  45.  
  46.      p = q;
  47.      set = !set;
  48.   }
  49.   mat[i] = NULL;
  50.  
  51.   mat = realloc(mat, ++i * sizeof *mat);
  52.  
  53.   return mat;
  54. }

La salida es la esperada:
Código:
 0:  01
 1:  ab
 2: 210
 3:   c

También pueden utilizarse otras funciones, por ejemplo sscanf.

Un saludo


Título: Re: Ayuda con código para re ordenar array
Publicado por: 85 en 5 Abril 2013, 14:38 pm
aweee k nivel   ;D


Título: Re: Ayuda con código para re ordenar array
Publicado por: leosansan en 5 Abril 2013, 18:28 pm
Creo que con un contador, bandera o flag y un array para guardar los parciales "va que chuta":

Código
  1. 01ab210c213qwe31zxc213
  2.  
  3. 01
  4. ab
  5. 210
  6. c
  7. 213
  8. qwe
  9. 31
  10. zxc
  11. 213
  12. Presione una tecla para continuar . . .
  13.  

Código
  1.  
  2. #include<stdio.h>
  3.  
  4. int main(){
  5.  
  6.    int i,j=0,k=0,cont=0;
  7.    char cadena[80]="01ab210c213qwe31zxc213";;
  8.    char array_de_cadena[40][6] = {{0}};
  9.    puts("01ab210c213qwe31zxc213\n");
  10. //scanf("%s", cadena);
  11. for (i=0;cadena[i]!='\0';i++){
  12.        if (cadena[i]>47 && cadena[i]<58 ){
  13.            if (cont==1){
  14.                array_de_cadena[j][k]='\0';j++;k=0;
  15.            }
  16.        array_de_cadena[j][k]=cadena[i];k++;cont=2;
  17.        }
  18.        else {
  19.            if (cont==2){
  20.                array_de_cadena[j][k]='\0';j++;k=0;
  21.            }
  22.            array_de_cadena[j][k]=cadena[i];k++;cont=1;
  23.        }
  24.   }
  25.    for (i=0;i<=j;i++)
  26.        printf ("%s \n",array_de_cadena[i]);
  27.    return 0;
  28. }
  29.  

Saluditos!. ...(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Ayuda con código para re ordenar array
Publicado por: 85 en 5 Abril 2013, 21:19 pm
eiiiii no vale poner varias cosas en una línea para que parezca más corto XD


Título: Re: Ayuda con código para re ordenar array
Publicado por: leosansan en 5 Abril 2013, 23:20 pm
eiiiii no vale poner varias cosas en una línea para que parezca más corto XD


 ;-) ;-) ;-) Lo "rectifico" y aún así, además de corto es "simple" siguiendo el principio de la navaja de Ockham: «en igualdad de condiciones, la explicación más sencilla suele ser la correcta»

Código
  1. #include<stdio.h>
  2.  
  3. int main(){
  4.  
  5.    int i,j=0,k=0,cont=0;
  6. char cadena[80]="01ab210c213qwe31zxc213";;
  7.    char array_de_cadena[40][6] = {{0}};
  8. puts("01ab210c213qwe31zxc213\n");
  9.    for (i=0;cadena[i]!='\0';i++){
  10.        if (cadena[i]>47 && cadena[i]<58 ){
  11.            if (cont==1){
  12.                array_de_cadena[j][k]='\0';
  13.                j++;
  14.                k=0;
  15.            }
  16.        array_de_cadena[j][k]=cadena[i];
  17.        k++;
  18.        cont=2;
  19.        }
  20.        else {
  21.            if (cont==2){
  22.                array_de_cadena[j][k]='\0';
  23.                j++;
  24.                k=0;
  25.            }
  26.            array_de_cadena[j][k]=cadena[i];
  27.            k++;
  28.            cont=1;
  29.        }
  30.   }
  31.    for (i=0;i<=j;i++)
  32.        printf ("%s \n",array_de_cadena[i]);
  33.    return 0;
  34. }
  35.  

Un abrazo y Saluditos!. ....(http://smilies-gifs.com/emoticonos-grandes/21grandes.gif)

P.D: Sería más corto con el uso de sscanf, pero no sería más simple ni en igualdad de condiciones respecto a los propuestos.


Título: Re: Ayuda con código para re ordenar array
Publicado por: rir3760 en 6 Abril 2013, 05:50 am
Sería más corto con el uso de sscanf, pero no sería más simple ni en igualdad de condiciones respecto a los propuestos.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(void)
  5. {
  6.   char *cad = "01ab210c213qwe31zxc213";
  7.   char tok[40][6] = {{0}};
  8.   int i;
  9.   int j;
  10.   int nc;
  11.  
  12.   puts("01ab210c213qwe31zxc213");
  13.  
  14.   i = 0;
  15.   while (
  16.      sscanf(cad,  "%[0123456789]%n", tok[i], &nc) == 1 ||
  17.      sscanf(cad, "%[^0123456789]%n", tok[i], &nc) == 1
  18.   ){
  19.      cad += nc;
  20.      i++;
  21.   }
  22.  
  23.   for (j = 0; j < i; j++)
  24.      printf ("tok[%d] == %s\n", j, tok[j]);
  25.  
  26.   return 0;
  27. }

A mi me parece aceptable (no hay nada realmente complicado).

----

Edito:

Por otra parte si la aproximación debe ser "simplicidad a rajatabla" (no me gusta ya que la biblioteca estándar esta para eso: para explotarla) podemos basarnos en una operación XOR:
Código
  1. #include <stdio.h>
  2.  
  3. #define IS_DIGIT(ch) ((ch) >= '0' && (ch) <= '9')
  4.  
  5. int main(void)
  6. {
  7.   char cad[] = "01ab210c213qwe31zxc213";
  8.   char tok[40][6] = {{0}};
  9.   int i;
  10.   int j;
  11.   int k;
  12.  
  13.   puts("01ab210c213qwe31zxc213");
  14.  
  15.   j = 0;
  16.   k = 0;
  17.   for (i = 0; cad[i] != '\0'; i++){
  18.      tok[j][k] = cad[i];
  19.  
  20.      if (IS_DIGIT(cad[i]) ^ IS_DIGIT(cad[i + 1])){
  21.         j++;
  22.         k = 0;
  23.      }else
  24.         k++;
  25.   }
  26.  
  27.   for (i = 0; i < j; i++)
  28.      printf("tok[%d] == %s\n", i, tok[i]);
  29.  
  30.   return 0;
  31. }

Por supuesto con las limitaciones que tiene el uso del array para almacenar los tokens: resultados incorrectos si se sobrepasa la capacidad del elemento (token) o del array en si.

----

Edito 2:

Cambie la versión utilizando sscanf por una ultima mas corta (y por supuesto mas fea). Y no tienen que preguntarme: ya no es tan aceptable (esto ultimo hay que tomarlo con un poco de humor).

Un saludo


Título: Re: Ayuda con código para re ordenar array
Publicado por: leosansan en 6 Abril 2013, 14:43 pm
"Sin dudarlo un instante" me quedo con el segundo. Es una simplificación del mío al mirar un caracter y el siguiente y decidir en función de ello lo que hacer.

Código
  1. #include<stdio.h>
  2.  
  3. int main(){
  4.  
  5.    int i,j=0,k=0,cont=0;
  6. char cadena[80]="01ab210c213qwe31zxc213";
  7.    char array_de_cadena[40][6] = {{0}};
  8. puts("01ab210c213qwe31zxc213\n");
  9.    for (i=0;cadena[i]!='\0';i++){
  10.         array_de_cadena[j][k]=cadena[i];
  11.        if ((cadena[i]>47 && cadena[i]<58) ^ (cadena[i+1]>47 && cadena[i+1]<58)){
  12.                j++;
  13.                k=0;
  14.        }
  15.            else
  16.                k++;
  17.        }
  18.    for (i=0;i<=j;i++)
  19.        printf ("%s \n",array_de_cadena[i]);
  20.    return 0;
  21. }

Muy agudo rir.
Sólo me queda la duda de no introducir el caracter nulo al final de cada cadena.


Saluditos!. ...(http://st.forocoches.com/foro/images/smilies/ciao.gif)

P.D: Lo que no entiendo es a cuento de que vino el código que habías posteado anteriormente  :silbar:


Título: Re: Ayuda con código para re ordenar array
Publicado por: 85 en 6 Abril 2013, 16:12 pm
rir usando macros para hacer el código más legible?  ;-)


Título: Re: Ayuda con código para re ordenar array
Publicado por: rir3760 en 6 Abril 2013, 18:19 pm
Sólo me queda la duda de no introducir el caracter nulo al final de cada cadena.
No hay problema. Cuando se declara un array y se inicializa mediante una lista de valores:
Código
  1. char tok[40][6] = {{0}};
Los valores faltantes se toman como cero.

P.D: Lo que no entiendo es a cuento de que vino el código que habías posteado anteriormente :silbar:
¿El primero? Me parecio un buen ejemplo del uso de un interruptor y punteros a funciones.

rir usando macros para hacer el código más legible?  ;-)
No la veo mal. La alternativa era isdigit pero esta no garantiza el resultado uno o cero, se debe forzar y con ello el condicional (con macro):
Código
  1. if (IS_DIGIT(cad[i]) ^ IS_DIGIT(cad[i + 1])){
Termina así (con isdigit):
Código
  1. if (!!isdigit(cad[i]) ^ !!isdigit(cad[i + 1])){
En mi opinión demasiado forzado, a falta de opciones no queda mas (remedio) que utilizar la macro.

Un saludo


Título: Re: Ayuda con código para re ordenar array
Publicado por: 85 en 7 Abril 2013, 16:37 pm
Si eso estaba puesto para inicializar en cero..
Y con respecto a mi segundo código y el primero de rir, usaban memoria dinámica porque no se sabe cuántos bloques (de letras o números) van a resultar. Lo que pasa que asumimos un número así por decir 40 para hacerla más fácil.