C/Visual C - triple punteros

   
Vista:

triple punteros

Publicado por Jesus (4 intervenciones) el 17/09/2017 17:39:45
Buenos días.

Mi duda es la siguiente:

Quiero pasar una matriz tipo float, a una función por referencia. Dicha función llenará la matriz desde un archivo de texto suministrado por el usuario. Tanto el código como el archivo de prueba, se muestra abajo.

El código compila correctamente (estoy usando gcc), no obstante, cuando hago las pruebas, no trabaja.

Agradezco mucho si alguien puede explicarme las razones de este mal funcionamiento.

Atentamente,
Jesús David

----------------------------------------------------------
-------------------Código fuente----------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void LeerDatos(char stNombre[30], long *iDeep, long *iConst, long *iGen, int *iNivel, float ***dAb);
 
int main (void)
{
	char stNombre[30], stLine[300];
	long iDeep,iConst,iGen,i,j;
	int iNivel;
	float **dAb;
 
	printf("Introduzca el nombre del archivo: \n");
	scanf("%s",stNombre);
 
	LeerDatos(stNombre, &iDeep, &iConst, &iGen, &iNivel, &dAb);
 
	printf("iDeep: %ld, iConst: %ld, iGen: %ld, iNivel: %d",iDeep,iConst,iGen,iNivel);
 
	for (i=0;i<iConst;i++)
	{
		for (j=0;j<(iGen)+1;j++)
		{
			printf("%1f ",dAb[i][j]);
		}
		printf("\n");
	}
 
	return 0;
}
 
void LeerDatos(char stNombre[30], long *iDeep, long *iConst, long *iGen, int *iNivel, float ***dAb)
{
	FILE *fp;
	long i,j;
	float dTmp;
	char stTmp[40];
 
	fp = fopen (stNombre, "r");
	if (fp==NULL)
	{
		fputs ("File error",stderr);
		exit (1);
	}
 
	fscanf(fp,"%ld",iDeep);
	fgets(stTmp,40,fp); // Lectura temporal
 
	fscanf(fp,"%ld",iConst);
	fgets(stTmp,40,fp); // Lectura temporal
 
	fscanf(fp,"%ld",iGen);
	fgets(stTmp,40,fp); // Lectura temporal
 
	fscanf(fp,"%d",iNivel);
	fgets(stTmp,40,fp); // Lectura temporal
 
	*dAb=(float **) malloc(*iConst*sizeof(float *));
	for (i=1;i<*iConst;i++) *dAb[i]=malloc(((*iGen)+1)*sizeof(float));
 
	/* -&gt; Llenado de la matriz */
	for (i=0;i<*iConst;i++)
	{
		for (j=0;j<(*iGen)+1;j++)
		{
			fscanf(fp,"%1f",&dTmp);
			*dAb[i][j]=dTmp;
		}
		printf("\n");
	}
 
	fclose (fp);
}
--------------------------------------------------

--------------------------------------------------
-------------prueba.txt------------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
600000 Densidad Grid Integración
17 Número de restricciones
7 Número de generadores
2 Niveles
 1 2 0 0 0 0 0 1000
 -1 0 0 0 0 0 0 0
 0 1 0 0 0 0 0 150
 0 -1 0 0 0 0 0 0
 0 0 1 0 0 0 0 324
 0 0 -1 0 0 0 0 0
 0 0 0 1 0 0 0 1250
 0 0 0 -1 0 0 0 0
 0 0 0 0 1 0 0 396
 0 0 0 0 -1 0 0 0
 0 0 0 0 0 1 0 276
 0 0 0 0 0 -1 0 0
 0 0 0 0 0 0 1 224
 0 0 0 0 0 0 -1 0
 -0.012903 -0.078602 -0.031037 -0.022796 -0.005934 -0.03496 0.017291 -5.55323109732788
 -0.024644 -0.039737 -0.030382 -0.026945 -0.014107 -0.030527 0.012554 -11.995211073984
 -0.064922 -0.081875 -0.052525 -0.069701 -0.01974 -0.055846 0.085246 -98.410734867
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

triple punteros

Publicado por Tom (574 intervenciones) el 17/09/2017 18:19:26
¿ Qué quieres decir con "no trabaja" ?
Y ¿ Con qué fin usas float *** ?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

triple punteros

Publicado por Jesus (4 intervenciones) el 17/09/2017 18:30:08
Buen día.

Muchas gracias por interesarse en mi inquietud.

En cuanto a "no trabaja", significa que cuando lo corro, me aparece este mensaje "prueba1.exe dejó de funcionar"

Referente al uso de float ***, lo hago por que necesito pasar una matriz por referencia. No lo quiero como resultado de una función.

Espero haber solucionado la inquietud para poder avanzar en este tema.

Muchas gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

triple punteros

Publicado por Tom (574 intervenciones) el 17/09/2017 18:35:44
Pon en tu código algún mensaje que indique por dónde va pasando, y el contenido de alguna variable importante. O utiliza un debuger. El caso es que deberías ver tú mismo dónde se produce el fallo crítico.
Casi con toda seguridad, estás escribiendo más datos de la memoria que reservas con malloc.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

triple punteros

Publicado por Jesus (4 intervenciones) el 17/09/2017 18:45:16
Muchas gracias Tom. Seguiré su recomendación.

Jesús
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

triple punteros

Publicado por Jesus David (1 intervención) el 18/09/2017 02:25:51
Luego de analizar bien el código, adjunto versión del código que lee una matriz de un archivo de texto desde una función en C. Dicha matriz es pasada por referencia y por lo tanto es usado un triple puntero.

El código a continuación


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/* -&gt; Definición de librerías */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
/* -&gt; Declaración de funciones */
void LeerDatos(char stNombre[30], long *iDeep, long *iConst, long *iGen, int *iNivel, float ***dAb);
 
/* Función principal */
int main (void)
{
	/* -&gt; Declaración de variables */
	char stNombre[30], stLine[300];
	long iDeep,iConst,iGen,i,j;
	int iNivel;
	float **dAb;
 
 
	/* -&gt; Solicitud del nombre del archivo al usuario */
	printf("Introduzca el nombre del archivo: \n");
	scanf("%s",stNombre); /*Cada espacio en la frase es para una variable nueva*/
 
	LeerDatos(stNombre, &iDeep, &iConst, &iGen, &iNivel, &dAb);
 
	printf("iDeep: %ld, iConst: %ld, iGen: %ld, iNivel: %d\n",iDeep,iConst,iGen,iNivel);
 
	for (i=0;i<iConst;i++)
	{
		for (j=0;j<(iGen)+1;j++)
		{
			printf("%f ",dAb[i][j]);
		}
		printf("\n");
	}
 
	/* Se libera la memoria de las matrices */
	free(dAb[0]);
	free(dAb);
	dAb=NULL;
 
	return 0;
}
 
void LeerDatos(char stNombre[30], long *iDeep, long *iConst, long *iGen, int *iNivel, float ***dAb)
{
	/* -&gt; Declaración de variables */
	FILE *fp;
	long i,j;
	float dTmp;
	char stTmp[40];
 
	/* -&gt; Apertura del archivo y lectura de variables */
	fp = fopen (stNombre, "r");
	if (fp==NULL)
	{
		fputs ("File error",stderr);
		exit (1);
	}
 
	fscanf(fp,"%ld",iDeep); // Lectura de la profundidad
	fgets(stTmp,40,fp); // Lectura temporal
 
	fscanf(fp,"%ld",iConst); // Lectura del número de restricciones
	fgets(stTmp,40,fp); // Lectura temporal
 
	fscanf(fp,"%ld",iGen); // Lectura del número de generadores
	fgets(stTmp,40,fp); // Lectura temporal
 
	fscanf(fp,"%d",iNivel); // Lectura del número de niveles
	fgets(stTmp,40,fp); // Lectura temporal
 
	/* -&gt; Dimensionamiento de la matriz */
	(*dAb)=malloc(*iConst*sizeof(float *));
	(*dAb)[0]=(float *) malloc(*iConst*((*iGen)+1)*sizeof(float));
	for (i=1;i<*iConst;i++) (*dAb)[i]=(*dAb)[i-1]+((*iGen)+1);
 
	/* -&gt; Llenado de la matriz */
	for (i=0;i<*iConst;i++)
	{
		for (j=0;j<(*iGen)+1;j++)
		{
			fscanf(fp,"%f",&dTmp);
			(*dAb)[i][j]=dTmp;
		}
	}
 
	/* -&gt; Cierre del archivo */
	fclose (fp);
}

-----------------------------------------------------------
-------------------Prueba1.txt------------------------
600000 Densidad Grid Integración
17 Número de restricciones
7 Número de generadores
2 Niveles
1 2 0 0 0 0 0 1000
-1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 150
0 -1 0 0 0 0 0 0
0 0 1 0 0 0 0 324
0 0 -1 0 0 0 0 0
0 0 0 1 0 0 0 1250
0 0 0 -1 0 0 0 0
0 0 0 0 1 0 0 396
0 0 0 0 -1 0 0 0
0 0 0 0 0 1 0 276
0 0 0 0 0 -1 0 0
0 0 0 0 0 0 1 224
0 0 0 0 0 0 -1 0
-0.012903 -0.078602 -0.031037 -0.022796 -0.005934 -0.03496 0.017291 -5.55323109732788
-0.024644 -0.039737 -0.030382 -0.026945 -0.014107 -0.030527 0.012554 -11.995211073984
-0.064922 -0.081875 -0.052525 -0.069701 -0.01974 -0.055846 0.085246 -98.410734867
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

triple punteros

Publicado por chema@linux.es (234 intervenciones) el 18/09/2017 22:07:46
Como ejercicio puede , como ejemplo es pésimo.

No uses fscanf ni fget ni similares para la lectura de un fichero.

la matriz que intentas crear se puede emular de forma mas sencilla con una matriz escalar (mismo tipo consecutivo).

Si pretendes usar float . piensa que vale para poco más que almacenar números grandes sin precisión, float no es valido para realizar sumas correctas como , sumar moneda con dos o tres decimales, para sumas con decimales, fijos se usa un tipo int de tamaño 8 y los decimales se colocan "por posición", para sumas de decimales variables debes que crea un tipo. (struct)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de gregory

triple punteros

Publicado por gregory (21 intervenciones) el 14/10/2017 00:25:08
No podrías mejor usar un struct en vez de array o matriz.

Para no tener que pasar tanto parametros.
asi organizarias mejor los datos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

triple punteros

Publicado por Jesus (4 intervenciones) el 14/10/2017 03:31:48
Muchas gracias Gregory.

Tiene razón. En mis códigos actuales, después de profundizar un poco más en los conceptos de C, estoy implementando estructuras para el manejo de matrices.

Muchas gracias por la recomendación.

Jesús
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Revisar política de publicidad