Ir al contenido


Foto

Como leer matriz en un archivo de texto? Programa de prueba en C.


Mejor respuesta robert01 , 23 febrero 2023 - 09:03

Ya encontré la solución luego de probar de todo. Solo cambié el valor 0 de tamano por 1. Saludos

Ir al mensaje completo


  • Por favor identifícate para responder
5 respuestas en este tema

#1 robert01

robert01

    Advanced Member

  • Miembros
  • PipPipPip
  • 162 mensajes
  • LocationArgentina

Escrito 22 febrero 2023 - 06:01

Hola. ¿Como les va a todos? Tengo un pequeño problema. Esta parte de código en C es para abrir y leer una matriz en un archivo de texto. El problema que tiene es que no lee correctamente si es de 4 x 4, lee como si fuera de 3x3 y con errores. Hay algo que no veo. No se programar en c.


php
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "mi_libreria.h"
  4.  
  5. int main() {
  6. int tamano;
  7. double** matriz;
  8.  
  9.  
  10. FILE* archivo = fopen("matriz.txt", "r");
  11. if (archivo == NULL) {
  12. printf("No se pudo abrir el archivo\n");
  13. return 1;
  14. }
  15.  
  16. // Contar número de filas
  17. tamano = 0;
  18. while (!feof(archivo)) {
  19. char c = fgetc(archivo);
  20. if (c == '\n') {
  21. tamano++;
  22. }
  23. }
  24. rewind(archivo); // Volver al inicio del archivo
  25.  
  26. // Crear matriz
  27. matriz = (double**)malloc(tamano * sizeof(double*));
  28. for (int i = 0; i < tamano; i++) {
  29. matriz[i] = (double*)malloc(tamano * sizeof(double));
  30. }
  31.  
  32. // Leer valores
  33. for (int i = 0; i < tamano; i++) {
  34. for (int j = 0; j < tamano; j++) {
  35. if (fscanf(archivo, "%lf", &matriz[i][j]) != 1) {
  36. printf("Error al leer el archivo\n");
  37. return 1;
  38. }
  39. }
  40. }
  41.  
  42. for (int i = 0; i < tamano; i++) {
  43. for (int j = 0; j < tamano; j++) {
  44. printf("%10.6f ", matriz[i][j]);
  45. }
  46. printf("\n");
  47. }
  48.  
  49. fclose(archivo);
  50. printf("\n");
  51.  
  52.  
  53. calcular_matriz_inversa(matriz, tamano);
  54.  
  55. for (int i = 0; i < tamano; i++) {
  56. for (int j = 0; j < tamano; j++) {
  57. printf("%10.6f ", matriz[i][j]);
  58. }
  59. printf("\n");
  60. }
  61.  
  62. for (int i = 0; i < tamano; i++) {
  63. free(matriz[i]);
  64. }
  65. free(matriz);
  66.  
  67. return 0;
  68. }

Gracias


Editado por robert01, 22 febrero 2023 - 06:27 .

  • 0

#2 robert01

robert01

    Advanced Member

  • Miembros
  • PipPipPip
  • 162 mensajes
  • LocationArgentina

Escrito 23 febrero 2023 - 09:03   Mejor respuesta

Ya encontré la solución luego de probar de todo. Solo cambié el valor 0 de tamano por 1. Saludos


  • 0

#3 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 24 febrero 2023 - 09:27

Ya encontré la solución luego de probar de todo. Solo cambié el valor 0 de tamano por 1. Saludos

 

 

Que bien robert01,

 

Lo que no sabemos C aprendimos algo hoy.

 

Saludos


  • 0

#4 robert01

robert01

    Advanced Member

  • Miembros
  • PipPipPip
  • 162 mensajes
  • LocationArgentina

Escrito 25 febrero 2023 - 04:17

Hola Egostar!

 

Es increíble pero si sabía algo de C pero no me acordaba por el paso del tiempo. Ayer encontré un código muy parecido a este como parte de un programa que había hecho en 2005 en unos backup.

 

Ese código que puse ahí fue generado por www.chat.openai.com. Se me ocurrió probar que podía llegar a obtener preguntando.

 

El código de la dll es:


cpp
  1. #include "inversa.h"
  2.  
  3. __declspec(dllexport) calcular_matriz_inversa(double** matriz, int tamano) {
  4. // Implementación del cálculo de la matriz inversa
  5. }
  6.  
  7. void calcular_matriz_inversa(double **matriz, int tamano) {
  8. double temp;
  9. int i, j, k;
  10. double identidad[tamano][tamano];
  11.  
  12. // Inicializar la matriz identidad
  13. for (i = 0; i < tamano; i++) {
  14. for (j = 0; j < tamano; j++) {
  15. identidad[i][j] = (i == j) ? 1 : 0;
  16. }
  17. }
  18.  
  19. // Convertir la matriz original en una matriz triangular superior
  20. for (i = 0; i < tamano; i++) {
  21. for (j = i + 1; j < tamano; j++) {
  22. temp = matriz[j][i] / matriz[i][i];
  23. for (k = i; k < tamano; k++) {
  24. matriz[j][k] -= temp * matriz[i][k];
  25. }
  26. for (k = 0; k < tamano; k++) {
  27. identidad[j][k] -= temp * identidad[i][k];
  28. }
  29. }
  30. }
  31.  
  32. // Convertir la matriz triangular superior en la matriz identidad
  33. for (i = tamano - 1; i >= 0; i--) {
  34. for (j = i - 1; j >= 0; j--) {
  35. temp = matriz[j][i] / matriz[i][i];
  36. for (k = 0; k < tamano; k++) {
  37. identidad[j][k] -= temp * identidad[i][k];
  38. }
  39. }
  40. }
  41.  
  42. // Normalizar la matriz identidad
  43. for (i = 0; i < tamano; i++) {
  44. temp = matriz[i][i];
  45. for (j = 0; j < tamano; j++) {
  46. identidad[i][j] /= temp;
  47. }
  48. }
  49.  
  50. // Copiar la matriz inversa en la matriz original
  51. for (i = 0; i < tamano; i++) {
  52. for (j = 0; j < tamano; j++) {
  53. matriz[i][j] = identidad[i][j];
  54. }
  55. }
  56. }


php
  1. #ifndef DLL_INVERSA_H
  2. #define DLL_INVERSA_H
  3.  
  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif
  7.  
  8. void calcular_matriz_inversa(double *matriz, int tamano, double *matriz_inversa);
  9.  
  10. #ifdef __cplusplus
  11. }
  12. #endif
  13.  
  14. #endif

Saludos

 


  • 0

#5 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 25 febrero 2023 - 09:05

El problema lo tienes si la última linea de tu archivo de texto no termina en un retorno de línea '\n', entonces feof en ese punto es cierto y con elle te falta una linea por contar.

 

Pero si no es el caso vas a tener un problema. Imagina que después de escribir tu matriz de 4x4 hay varios retornos de línea, tu código fallará. O tienes bien definido y limitado es número de retornos de línea que se pueden escribir al final del archivo, o tienes que ajustar el código de lectura.

 

Para el caso de necesitar el control de este asunto, propongo este ajuste que te permite leer el tamaño independientemente de si hay uno, ninguno o cientos de retornos al acabar tu archivo:


cpp
  1. // Calculando el tamaño del archivo
  2. fseek(archivo, 0, SEEK_END);
  3. long Size = ftell(archivo);
  4. fseek(archivo, 0, SEEK_SET);
  5.  
  6. // Reservando un buffer suficientemente grande
  7. char *buffer = (char*)malloc(Size);
  8.  
  9. // Leyendo el número de líneas útiles del archivo
  10. tamano = 0;
  11. while(fgets(buffer, Size, archivo) && *buffer != '\n') tamano++;
  12. free(buffer);

Saludos.

 


  • 0

#6 robert01

robert01

    Advanced Member

  • Miembros
  • PipPipPip
  • 162 mensajes
  • LocationArgentina

Escrito 25 febrero 2023 - 10:27

El problema lo tienes si la última linea de tu archivo de texto no termina en un retorno de línea '\n', entonces feof en ese punto es cierto y con elle te falta una linea por contar.

 

Pero si no es el caso vas a tener un problema. Imagina que después de escribir tu matriz de 4x4 hay varios retornos de línea, tu código fallará. O tienes bien definido y limitado es número de retornos de línea que se pueden escribir al final del archivo, o tienes que ajustar el código de lectura.

 

Para el caso de necesitar el control de este asunto, propongo este ajuste que te permite leer el tamaño independientemente de si hay uno, ninguno o cientos de retornos al acabar tu archivo:


cpp
  1. // Calculando el tamaño del archivo
  2. fseek(archivo, 0, SEEK_END);
  3. long Size = ftell(archivo);
  4. fseek(archivo, 0, SEEK_SET);
  5.  
  6. // Reservando un buffer suficientemente grande
  7. char *buffer = (char*)malloc(Size);
  8.  
  9. // Leyendo el número de líneas útiles del archivo
  10. tamano = 0;
  11. while(fgets(buffer, Size, archivo) && *buffer != '\n') tamano++;
  12. free(buffer);

Saludos.

Hola Escafandra. Gracias por tu aporte. Ya voy a probar cuando consiga que el compilador se pueda ejecutar. No se porque ahora me dice que no puede reconocer gcc.

 

Saludos


  • 0




IP.Board spam blocked by CleanTalk.