CAAD
http://foro.caad.es/

Averiguar longitud de un string
http://foro.caad.es/viewtopic.php?f=12&t=3382
Página 1 de 2

Autor:  Makinaimo [ 05 Nov 2009 03:32 ]
Asunto:  Averiguar longitud de un string

Hola. Estoy intentando programar una barra de estado para GLULX que se limite a imprimir
centrado el nombre de la localidad actual del PJ, al estilo de la que usa la aventura de
Mastodon: 'Amanda'; pero no se cómo se consigue el número de caracteres que forman el
nombre de la localidad. ¿Alguien puede echarme una mano?

Como siempre, gracias adelantadas. ¡Y un saludo!

Autor:  mastodon [ 05 Nov 2009 08:04 ]
Asunto:  Re: Averiguar longitud de un string

Hola, Makinaimo, si no recuerdo mal, la función la copié del DM4 (uno de los ejercicios). No estoy seguro de si funciona también en Glulx, prueba a ver. Es esta:

Código:
[ DrawStatusLine i j;
  i = 0->33;
  font off;
  @split_window 1; @buffer_mode 0; @set_window 1;
  style reverse; @set_cursor 1 1; spaces(i);
  @output_stream 3 printed_text;
  print (name) location;
  @output_stream -3;
  j = (i-(printed_text-->0))/2;
  @set_cursor 1 j; print (name) location; spaces(j-1);
  style roman;
  @buffer_mode 1; @set_window 0; font on;
];

Autor:  baltasarq [ 05 Nov 2009 10:03 ]
Asunto:  Re: Averiguar longitud de un string

Hola !

En Inform, las cadenas no tienen las mismas características que en el resto de lenguajes de programación. Parece ser que tiene que ver con que están encriptadas, aunque yo no acabo de verle el sentido al tema.

Primero tendrás que pasar la cadena a un vector de caracteres, y luego tomar la longitud de la cadena, que se encuentra en la primera posición de ese vector "a la" pascal. Del ejemplo expuesto por Mastodon, las líneas que hacen eso son:

Código:
  @output_stream 3 printed_text;
  print (name) location;
  @output_stream -3;
  j = (i-(printed_text-->0))/2;


Lo que hace es una cosa rara que tiene inform: abre una canal de caracteres (dirigido a una variable llamada printed_text), imprime algo en él (en este caso, el nombre de la localidad), y lo cierra.

De hecho, en una librería anglo llamada istring.h, vemos lo siguiente en una función que convierte una cadena en un vector de caracteres:

Código:
if (litstr ofclass string)
    litstr.print_to_array(str);
   else
   {
    @output_stream 3 str;
    litstr();
    @output_stream -3;
   }
   return str-->0;


Es decir, la versión corta, con esa llamada a print_to_array(), funciona para cadenas, mientras que el método del @output_stream (Que sólo funcionará en Z) es más elaborado, permite imprimir cualquier cosa en ese canal y convertirlo a una cadena de caracteres.

En este momento, printed_text es un vector de caracteres, cuya longitud podemos tomar de:

Código:
  printed_text-->0;


De ahí que:

Código:
j = (i-(printed_text-->0))/2;


Resulte en la columna correcta para imprimir centrado el nombre de la localidad. (Ya que 'i' es el número de columnas de la ventana de texto).

Aquí, por cierto, tenemos otro punto importante de incompatibilidad con Glulx: 0->33 lo que hace es leer información de la cabecera del archivo Z, por lo que no funcionará para Glulx.

Tampoco sentencias como style reverse o @set_cursor, que son exclusivas de la máquina Z, te funcionarán.

Si quieres que todo funcione en Z y en Glulx, tienes que tener en cuenta las particularidades de esta última: http://www.caad.es/informate/docs/gull/gull_3.html#8

Tendrás que duplicar el código de dibujarLineaEstado:

Código:
[ dibujarLineaEstado;

#Ifdef TARGET_GLULX;
! código para Glulx...
#else;
! código para máquina Z...
#Endif;
];


Como ves, la cosa no es complejísima, pero sí un tanto tediosa, si quieres hacer el código para Z o Glulx. Si sólo quieres que el código funcione en Z, entonces, no hay problema:

Presi tiene una completísima librería para dibujar líneas de estado; desafortunadamente, por lo que he podido ver en el código, (a no ser que haya estado viendo una versión anticuada), sólo funciona para máquina Z. Seguro que él nos confirma o nos saca del error. :-)

Autor:  presi [ 05 Nov 2009 12:25 ]
Asunto:  Re: Averiguar longitud de un string

baltasarq escribió:
Presi tiene una completísima librería para dibujar líneas de estado; desafortunadamente, por lo que he podido ver en el código, (a no ser que haya estado viendo una versión anticuada), sólo funciona para máquina Z. Seguro que él nos confirma o nos saca del error. :-)


No, funciona tanto para Z como para Glulx, las dos versiones que hay.

Autor:  Makinaimo [ 05 Nov 2009 14:12 ]
Asunto:  Re: Averiguar longitud de un string

Vaya, como siempre, muchas gracias por contestar tan rápido. :D

Por ahora, había modificado la barra de estado de la aventura para máquina-z copiando tal cuál el ejemplo del Designer's Manual, justo como has hecho tú Mastodon; el problema que tenía es ese que has comentado, baltasarq, que el método que dibuja la barra de estado en Z hace llamadas de bajo nivel que son incompatibles con GLULX (además del tema de los estilos de texto). Así que mi barra de estado GLULX imprime sólamente el nombre de la localidad, pero lo hace a la izquierda de la pantalla.

Y ahora mismo voy a echar un vistazo a tu librería, presi, a ver si soy capaz de conseguir algo.

P.D.: Baltasar, siempre me sorprenden tus mensajes por la cantidad de cosas que se pueden aprender de ellos.

Autor:  Al-Khwarizmi [ 05 Nov 2009 14:33 ]
Asunto:  Re: Averiguar longitud de un string

baltasarq escribió:
En Inform, las cadenas no tienen las mismas características que en el resto de lenguajes de programación. Parece ser que tiene que ver con que están encriptadas, aunque yo no acabo de verle el sentido al tema.


Es que no lo tiene... que un lenguaje dirigido específicamente a crear unos programas que toman como entrada y salida cadenas de texto, te haga la vida imposible a la hora de manipular cadenas de texto, no tiene ningún sentido lo mires por donde lo mires. Al menos no en 2009 (tal vez en la época en que se diseñó la máquina Z sí que lo tendría, no lo sé, pero es triste estar condicionados hoy por eso).

Autor:  Incanus [ 05 Nov 2009 14:48 ]
Asunto:  Re: Averiguar longitud de un string

Makinaimo escribió:
P.D.: Baltasar, siempre me sorprenden tus mensajes por la cantidad de cosas que se pueden aprender de ellos.


Escucha al Maestro.

Lee al Maestro.

Aprende del Maestro.

¡Grande, Baltasar!

Autor:  Makinaimo [ 05 Nov 2009 15:14 ]
Asunto:  Re: Averiguar longitud de un string

¡Hola de nuevo!

He estado ojeando tu librería para hacer barras de estado, Presi... y no me he enterado de casi nada. No quiero decir que sea difícil de usar (aunque no la he probado, parece muy sencillita, y potente), el problema es que no consigo entender cómo funciona. Y vaya, me ha picado la curiosidad y ahora no me conformo con que mi barra de estado funcione bien, me gustaría saber cómo lo hace.

¿Alguien puede explicarme mejor cómo transformar una cadena de texto en un array (tanto en Máquina-Z como en GLULX)?
¿Y la operación contraria? ¿Transformar un array de caracteres en una cadena de texto normal?

¡Gracias adelantadas otra vez!

Autor:  baltasarq [ 05 Nov 2009 17:26 ]
Asunto:  Re: Averiguar longitud de un string

Hola !

Incanus escribió:
¡Grande, Baltasar!


Bueh, he engordado un poco, pero tampoco es para tanto. :-)

Autor:  baltasarq [ 05 Nov 2009 17:29 ]
Asunto:  Re: Averiguar longitud de un string

Hola !

Makinaimo escribió:
¿Alguien puede explicarme mejor cómo transformar una cadena de texto en un array (tanto en Máquina-Z como en GLULX)?

Claro que sí (parece que, después de todo, no me explico tan bien):

Código:
Global buffer-->1024;

[ initialise x;
      x = "Hola";
      hola.print_to_array( buffer );
];



Después tendrás que moverte por ese vector letra a letra para hacerlo que sea: imprimirlo por pantalla... etc.

Citar:
¿Y la operación contraria? ¿Transformar un array de caracteres en una cadena de texto normal?


Claro que sí: no se puede. :roll:

Autor:  presi [ 05 Nov 2009 18:00 ]
Asunto:  Re: Averiguar longitud de un string

Makinaimo escribió:
He estado ojeando tu librería para hacer barras de estado, Presi... y no me he enterado de casi nada. No quiero decir que sea difícil de usar (aunque no la he probado, parece muy sencillita, y potente), el problema es que no consigo entender cómo funciona.


Yo hace tiempo que abandoné Inform, asi que si te digo la verdad yo tampoco me acuerdo exactamente de como funcionaba. Pero la ventaja de una librería es que no necesitas saber como funciona internamente para usarla.

Autor:  Makinaimo [ 05 Nov 2009 21:38 ]
Asunto:  Re: Averiguar longitud de un string

Creo que soy algo más torpe de lo que creía.
El código que me has pasado, baltasar, tiene alguna errata pequeña, pero funciona:

Código:
Array buf -> 1024;
[ Initialise x;
    x = "Hola";
    x.print_to_array( buf );
    print (string) x, "/ núm. de caracteres: ", buf-->0;
];


El problema es que ahora, desde dentro de mi rutina DrawStatusLine soy incapaz de almacenar en una variable el nombre de 'location'. La rutina hace un print (name) location; pero para guardar el nombre en una variable (pongamos 'x'), cosas que he intentado como x = location, x = (name) location, x = location.name o x = location.short_name, no funcionan. ¿Podéis echarme otro pequeño cable?

Autor:  DrVanHalenFan [ 05 Nov 2009 23:18 ]
Asunto:  Re: Averiguar longitud de un string

Makinaimo escribió:
El problema es que ahora, desde dentro de mi rutina DrawStatusLine soy incapaz de almacenar en una variable el nombre de 'location'. La rutina hace un print (name) location; pero para guardar el nombre en una variable (pongamos 'x'), cosas que he intentado como x = location, x = (name) location, x = location.name o x = location.short_name, no funcionan. ¿Podéis echarme otro pequeño cable?


La propiedad name hace referencia a una palabra (o lista de ellas) de diccionario, que no podrás manipular de ese modo, ya que no son "cadenas de caracteres" al uso. Parea Inform es como si fueran "numeritos" que hacen referencia a una posición de su diccionario interno creado en tiempo de compilación.

Es un tiro a ciegas, ya que no tengo abierto nada con que probarlo ahora mismo, pero prueba con la propiedad short_name. Esta se corresponde con el nombre entre comillas de la declaración del objeto (en este caso localidad) en su primera linea y es una cadena, así que lo mismo por ahí sí que consigues algo.

Autor:  Eliuk Blau [ 06 Nov 2009 04:47 ]
Asunto:  Re: Averiguar longitud de un string

DrVanHalenFan escribió:
Es un tiro a ciegas, ya que no tengo abierto nada con que probarlo ahora mismo, pero prueba con la propiedad short_name. Esta se corresponde con el nombre entre comillas de la declaración del objeto (en este caso localidad) en su primera linea y es una cadena, así que lo mismo por ahí sí que consigues algo.


Escribo cortito porque no tengo tiempo ahora (mañana te mandaré la solución, Makinaimo, porque yo ya lo he hecho hace un tiempo atrás)...

No, short_name() no sirve para eso. Esta propiedad sirve para declarar un nombre corto, que pueda ser variable dentro de la ejecución (programable). Lo nombres declarados en la cabecera del objeto, ejemplo: Object casa "La Casa de Pepe", son inmutables. short_name() sirve para hacerlos "mutables" por medio de programación. En este caso, el parser mira si el objeto tiene una propiedad short_name() y si es así la ejecuta con preferencia sobre el nombre del objeto en la cabecera.

Si se necesita imprimir el nombre guardado en la cabecera, se puede usar "print (object) casa"... o alternativamente "print (name) casa" [este último miraría si existe propiedad short_name() y la ejecutaría; en caso contrario, haría una impresión con (object)].

El viernes te copiaré un código que te servirá para hacer lo que quiere. :) Ahora estoy apuradito. :lol:

Saludos!

Autor:  Eliuk Blau [ 06 Nov 2009 04:52 ]
Asunto:  Re: Averiguar longitud de un string

baltasarq escribió:
Citar:
¿Y la operación contraria? ¿Transformar un array de caracteres en una cadena de texto normal?


Claro que sí: no se puede. :roll:


Sí se puede... pero de una forma muy turbia. Es un hacking que básicamente convierte un array en una "cadena de texto compactada", a la forma usal de máquina Z.

El "pero" es que ya no se puede imprimir la cadena simplemente con un print, sino que se de debe usar (address) para que funke el hack. Es bastante práctico (si es que realmente lo necesitas), pero no deja de ser un hack feo. :lol:

Página 1 de 2 Todos los horarios son UTC + 1 hora
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/