Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - rir3760

#91
Cita de: arkangel2006 en  8 Marzo 2015, 09:51 AMahora  compila y ejecuta pero cuando  tecleo la Opcion 1 y preciono ENTER  simplemente regresa al menu y asi con las otras Opciones
Eso sucede porque en la sentencia condicional switch:
Código (cpp) [Seleccionar]
switch (opc)
{
case 1:
{
   void lectura_datos(float *apun_trabajadores[10]);
   break;
}
case 2:
{
   void calcular_salarioTotal(float *apun_trabajadores[10]);
   break;
}
case 3:
{
   void imprimir_datos(float *apun_trabajadores[10]);
   break;
}
}

Lo que estas haciendo es declarar las funciones.

Para llamar a (ejecutar, invocar) una función debes indicar el nombre de esta seguido de sus argumentos (delimitados por paréntesis), de esta forma:
Código (cpp) [Seleccionar]
switch (opc){
case 1:
   lectura_datos(apun_trabajadores);
   break;
case 2:
   calcular_salarioTotal(apun_trabajadores);
   break;
case 3:
   imprimir_datos(apun_trabajadores);
   break;
}


Cita de: arkangel2006 en  8 Marzo 2015, 09:51 AM¿Por qué el arreglo bidimensional es declarado con un solo índice (solo se especifican las filas y no las columnas)?
float *apun_trabajadores[10];

¿Por qué se debe reservar espacio para las columnas? (malloc)
for(fila=0; fila<10; fila++) apun_trabajadores[fila]=(float*) malloc(6*sizeof(float));
Porque "apun_trabajadores" es un array de punteros, esto es, no almacena los valores directamente, en su lugar almacena las direcciones de las filas cada una con un tamaño fijo de seis elementos (las columnas) de tipo float.

Por eso primero reservas la memoria necesaria para cada fila guardando esta (la dirección) en el array.

En tu caso se puede utilizar un array de arrays (por ejemplo "float trab[10][6]") sin problemas, el porque se utiliza en su lugar un array de punteros mas reserva dinámica de memoria vía malloc se debe, supongo, al enunciado.

Un saludo
#92
Cita de: AxelP en  7 Marzo 2015, 23:33 PMAún no tengo claro con qué podría sustituir el new char, ya que mi propósito es usar C
Puedes utilizar new porque utilizas un compilador de C++, revisa con cuidado su documentación para saber como compilar el código fuente como C.

Cita de: AxelP en  7 Marzo 2015, 23:33 PMTampoco estoy seguro de por qué se debe de usar esto:
resultado[j] = char('0' + n[i]);
Porque los enteros 0, 1, 2, ... y los caracteres '0', '1', '2' ... se parecen (son enteros) pero no son los mismo (sus valores son diferentes).

Para obtener los dígitos 0, 1, 2, ... en base a los caracteres '0', '1', '2', ... debes restar '0'. Para explicarlo mejor:
'0' - '0' == 0
'1' - '0' == 1
...
'9' - '0' == 9

Y lo opuesto también aplica, para obtener los caracteres '0', '1', '2', ... en base a los dígitos 0, 1, 2, ... debes sumar '0':
0 + '0' == '0'
1 + '0' == '1'
...
9 + '0' == '9'

Ello porque los caracteres '0', '1', '2', ... tienen posiciones (valores) consecutivos y están ordenados de forma ascendente ('0', '1', '2', ...., '9').

Cita de: AxelP en  7 Marzo 2015, 23:33 PM
Y esto:
resultado[j] = '\0';
Porque en C una cadena es una secuencia de cero o mas caracteres seguidos del carácter '\0', este ultimo se utiliza para indicar el final de la cadena (si no lo colocas, ¿Como sabes donde termina?).

Cita de: AxelP en  7 Marzo 2015, 23:33 PMAdemas quisiera saber por qué en algunos char se debe poner char*, me dijeron que para que funcionara debía ponerlo, pero no se por qué.
Se utiliza "char *" para declarar una variable de tipo "puntero a carácter", ese tema lo veras mas adelante junto con los arrays.

Por ultimo si no tienes un curso o libro de calidad consigue uno, recomendaciones sobre ellos las puedes encontrar mediante el motor de búsqueda de los foros.

Un saludo
#93
Cita de: ivancea96 en  8 Marzo 2015, 14:57 PMYo te recomendaría declarar la función como bool, y, desde el lugar donde la llamas, hacer un:
Código (cpp) [Seleccionar]
while(sumando());

Y convertir el if en:

Código (cpp) [Seleccionar]
if(seguir == 1)
    return true;
else
    return false;
Ya que el resultado de los operadores relacionales es el esperado (true si se cumple la condición, falso en caso contrario) la sentencia condicional se puede eliminar quedando solo la sentencia de retorno:
Código (cpp) [Seleccionar]
return seguir == 1;

Un saludo
#94
Cita de: mataliebres en  6 Marzo 2015, 15:26 PMyo lo que quiero es leer de un archivo desde el final hasta el principio, pero por lo visto no se puede
Es posible y relativamente fácil en el caso de archivos binarios, en el caso de archivos de texto plano hay varias limitaciones.

Una aproximación consiste en leer cada uno de los caracteres en el archivo tomando nota cuando se requiera del inicio de cada linea mediante la función ftell. Ya con la posición de cada linea puedes utilizar fseek para posicionarte en la que tu quieras y leerla (recordando que las operaciones de lectura bien sobrescriben o agregan al final, no insertan).

Un programa de ejemplo donde se imprime cada una de las lineas de un archivo de texto empezando con la ultima y terminando con la primera:
#include <stdio.h>
#include <stdlib.h>

#define MAX_LINEAS  1024
#define MAX_CHARS   1024

#define NOM_ARCHIVO  "main.c"

int main(void)
{
   FILE *in;
   long pos[MAX_LINEAS];
   int num_pos;
   char linea[MAX_CHARS];
   int i;
   int ch;
   
   if ((in = fopen(NOM_ARCHIVO, "rt")) == NULL){
      perror(NOM_ARCHIVO);
      return EXIT_FAILURE;
   }
   
   /* Obtenemos la posicion de inicio de cada linea en el archivo */
   ch = '\n';
   num_pos = 0;
   do {
      if (ch == '\n' && (ch = fgetc(in)) != EOF){
         ungetc(ch, in);
         pos[num_pos++] = ftell(in);
      }
   }while ((ch = fgetc(in)) != EOF);
   
   /* Posicionamiento sobre cada linea de la ultima a la primera */
   i = num_pos;
   while (i > 0){
      i--;
      fseek(in, pos[i], SEEK_SET);
      fgets(linea, MAX_CHARS, in);
      printf("%s", linea);
   }
   fclose(in);
   
   return EXIT_SUCCESS;
}


Un saludo
#95
Cita de: mataliebres en  2 Marzo 2015, 11:49 AMpues no funciona como dices, lo que hace es sobreescribir el numero
Todas las operaciones en archivos sobrescriben o bien agregan al final

Cita de: mataliebres en  2 Marzo 2015, 11:49 AMpero lo que quiero es que se vayan añadiendo uno delante de otro
No es posible insertar en un archivo.

Hay varias alternativas, la mas sencilla consiste en:
1) Abres el archivo original y uno auxiliar.
2) Envías los datos como deseas al archivo auxiliar.
3) Cierras los archivos.
4) Eliminas el archivo original mediante la función remove.
5) Renombras el archivo auxiliar con el nombre del original mediante la función rename.

Un saludo
#96
Programación C/C++ / Re: Errores al compilar
6 Marzo 2015, 07:25 AM
Cita de: Jonathanxd en  6 Marzo 2015, 06:35 AM
porque se pone el asterisco?

Código (cpp) [Seleccionar]
void ordenar (int *ord);
void imprimir (int *impri);

En realidad no es necesario el cambio (es mas bien una cuestión de estilo).

Todo argumento que se declare en la forma "T nombre[N]", por ejemplo:
Código (cpp) [Seleccionar]
void ordenar (int ord[ALGUN_VALOR]);
void imprimir (int impri[ALGUN_VALOR]);

Se procesa como si la declaración fuera:
Código (cpp) [Seleccionar]
void ordenar (int *ord);
void imprimir (int *impri);

Ahí el asterisco indica que el argumento es un puntero, en tu caso la dirección en memoria del primer elemento del array. Revisa tu material de referencia y busca los apartados sobre punteros y arrays.

Un saludo
#97
El primer problema con el programa es que el lenguaje es C++ (la próxima vez por favor indícalo) pero no tiene casi nada de este (solo la reserva de memoria mediante new).

En la función de conversión los cambios a realizar son:
1) Debes reducir en una unidad el contador "i" antes de procesar cada dígito.
2) Cuando el dígito este en el rango 0 .. 9 para generar el carácter correspondiente debes utilizar:
Código (cpp) [Seleccionar]
resultado[j] = char('0' + n[i]);
3) Después del bucle y antes de la sentencia de retorno debes agregar el carácter de fin de cadena con:
Código (cpp) [Seleccionar]
   resultado[j] = '\0';

   return resultado;
}


Por ultimo en la función main debes imprimir el resultado mediante printf:
Código (cpp) [Seleccionar]
printf("El numero %d en base %d es: ", num, base);
printf("\"%s\"\n", conversion(num, base)); /* <== */
printf("\n\nQuieres convertir otro numero? Si=0/No=1 ");


Ya por ultimo deberías utilizar las facilidades del lenguaje, la función se puede reducir bastante, falta liberar la memoria utilizada y hay que evitar el uso de la biblioteca conio de Borland. Por favor lee el tema |Lo que no hay que hacer en C/C++. Nivel basico|

Un saludo
#98
Cita de: Reynega en  5 Marzo 2015, 18:14 PMModifique la función 'asignar', siguiendo tu recomendación. como resultado surgio un error en //ASIGNAR MEMORIA PARA CADA FILA
Debes pasar un puntero de tipo "char ***" y dentro de la función aplicar indireccion utilizando paréntesis, esto porque los operadores sufijos como "[]" tienen mayor prioridad que los prefijos como "*".

De esta forma:
void asignar(char ***matriz, int filas, int columnas)
{
   *matriz = malloc(filas * sizeof *matriz);
   
   for (int i = 0; i < filas; i++)
      (*matriz)[i] = malloc(columnas * sizeof *(*matriz)[i]);
}


Otro error se encuentra en la función que libera la memoria, la sentencia:
free(matriz + i);
Hay que cambiarla a:
free(matriz[i]);

----

Algunas recomendaciones:
* Evita el uso de la biblioteca conio de Borland, mas información en la pagina |Lo que no hay que hacer en C/C++. Nivel basico|.
* Las conversiones explicitas del valor retornado por las funciones malloc, calloc y realloc NO son necesarias y no se recomiendan.
* Cuando publiques código fuente utiliza las etiquetas de código, si utilizas las etiquetas para citar no se puede revisar el código fuente correctamente.

Un saludo
#99
Programación C/C++ / Re: programa punteros c
6 Marzo 2015, 03:01 AM
Cita de: chicainge en  5 Marzo 2015, 22:01 PMNo se por que el programa se salta el segundo scanf.
Como ya te comento ivancea96 el error se encuentra en la llamada a scanf:
scanf("vuelve a escribir un valor para dato(%d)\n",&p->dato2);

----

Solo para redondear el tema: cuando colocas texto literal en la cadena de formato este se consumirá solo si se encuentra literalmente en el stream (en este caso la entrada estándar).

En tu programa para que este genere la salida esperada debes introducir el primer numero, inmediatamente después el texto "vuelve a escribir un valor para dato(" y justo después de este el segundo numero. Por ejemplo:
introduce dato:
123vuelve a escribir un valor para dato(456  <== Entrada del programa
dato guardado con punto ((*D).dato) 123
introduce dato 2:
dato guardado por flecha(->) 456
Presione una tecla para continuar . . .


Un saludo
#100
Cita de: niraikanai en  2 Marzo 2015, 20:27 PMEstuve intentando leer un archivo de texto con el siguiente formato:

Pablo#10#7/12/1990

Estoy empezando a llegar a la conclusión de que no es posible leerlo con un solo fscanf con los siguientes parámetros:
fscanf(pF,"%s#%d/%d/%d",nombre,&dia,&mes,&ano);
Si tienes garantizada la estructura del archivo de texto puedes leer los cinco campos de cada registro con fscanf, un ejemplo de ello pero utilizando sscanf y un array para explicarlo mejor y de una manera mas fácil (eso espero) es:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   char *linea[] = {
      "Hugo#14#7/12/1990",
      "Paco#12#5/10/1988",
      "Luis#10#3/08/1986",
      "LINEA_SIN_EL_FORMATO_VALIDO"
   };
   
   char nombre[100];
   int num;
   int d;
   int m;
   int a;
   int i;
   
   for (
      i = 0;
      sscanf(linea[i], " %[^#]#%d#%d/%d/%d", nombre, &num, &d, &m, &a) == 5;
      i++
   )
      printf("%s %d %d/%d/%d\n", nombre, num, d, m, a);
   
   return EXIT_SUCCESS;
}


Otra opción es:
1) Leer cada linea con fgets.
2) Obtener cada uno de los componentes (separados por el carácter '#') con strtok.
3) Obtener los enteros del segundo y tercer componente con sscanf.

Un saludo