elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: AIO elhacker.NET 2021 Compilación herramientas análisis y desinfección malware


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  duda freopen
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: duda freopen  (Leído 3,019 veces)
pony012

Desconectado Desconectado

Mensajes: 2


Ver Perfil
duda freopen
« en: 19 Julio 2010, 16:10 pm »

bueno, pues según lo que leí el freopen sirve para abrir un archivo y asignarlo para el flujo de datos de entrada o de salida, por ejemplo, yo lo estoy usando para llenar unas matrices en un programa que intenta resolver algun sudoku, y mi problema es que no se como cerrar el archivo, y como lo asigno para que de ahi vengan los datos de entrada, pues ya no puedo aplicar algo para que el usuario salga del programa sin matarlo.
y esa es mi duda, como cerrar un archivo o volver a que los datos de entrada entren por el teclado y no por el archivo.

Por si lo quieren revisar, este es el codigo del programa, aun me falta mucho, pues ahora solo resuelve sudokus faciles, ya despues le intentare meter backtracking, pero por ahora es solo esto  :P
Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. int sudoku[9][9], matriz[9][9], seguros[9][9], posible=0, unicas=1;
  6. bool usado[10];
  7.  
  8. void imprimir();
  9. void unicas_soluciones();
  10. void comprobar(int a, int b);
  11.  
  12. int main()
  13. {
  14.  
  15.  
  16.    freopen("sudoku.txt","r",stdin);
  17.    for(int i=0; i<9; i++){
  18.            for(int j=0; j<9; j++){
  19.                    cin>>sudoku[i][j];
  20.                    }
  21.            }
  22.    freopen("config.txt","r",stdin);
  23.    for(int i=0; i<9; i++){
  24.            for(int j=0; j<9; j++){
  25.                    cin>>matriz[i][j];
  26.                    }
  27.            }
  28.    for(int i=0; i<9; i++){
  29.            for(int j=0; j<9; j++){
  30.                    if(sudoku[i][j]==0)seguros[i][j]=0;
  31.                    else seguros[i][j]=1;
  32.                    }
  33.            }
  34.  
  35.    imprimir();
  36.  
  37.    unicas_soluciones();
  38.  
  39.    imprimir();
  40.  
  41.  
  42.    while(cin.get() != '\n')
  43.    setbuf(stdin, '\0');
  44.    cin.get();
  45.    return 0;
  46. }
  47. void comprobar(int a, int b){
  48.    int sub_matriz=matriz[a][b];
  49.    int cont=0;
  50.    if(seguros[a][b]==0){
  51.                  for(int i=0; i<10; i++){
  52.                          usado[i]=0;
  53.                          }
  54.                  for(int i=0; i<9; i++){
  55.                               usado[sudoku[a][i]]=1;
  56.                               usado[sudoku[i][b]]=1;
  57.                          }
  58.                  for(int i=0; i<9; i++){
  59.                          for(int j=0; j<9; j++){
  60.                            if(sub_matriz==matriz[i][j]){
  61.                                                         usado[sudoku[i][j]]=1;
  62.                                                         }
  63.                            }
  64.                  }
  65.                  if(unicas==1){
  66.                          for(int i=0; i<10; i++){
  67.                                  if(usado[i]==0)cont++;
  68.                                  }
  69.                          if(cont==1){
  70.                                      posible=1;
  71.                                      cout<<"Posibles para "<<b+1<<","<<a+1<<endl;
  72.                                      for(int i=0; i<10; i++){
  73.                                              if(usado[i]==0){
  74.  
  75.                                                              seguros[a][b]=1;
  76.                                                              sudoku[a][b]=i;
  77.                                                              cout<<i<<endl;
  78.                                                              }
  79.                                              }
  80.  
  81.                                      }
  82.                                      }
  83.                          }
  84.    }
  85. void unicas_soluciones(){
  86.     posible=0;
  87.     for(int i=0; i<9; i++){
  88.             for(int j=0; j<9; j++){
  89.                     comprobar(i,j);
  90.                     }
  91.             }
  92.     cout<<"_________________"<<endl;
  93.     if(posible!=0) unicas_soluciones();
  94.     unicas=0;
  95.     }
  96. void imprimir(){
  97.     int counta=0,countb=0;
  98.     for(int i=0; i<9; i++){
  99.            for(int j=0; j<9; j++){
  100.                         cout<<sudoku[i][j];
  101.                         counta++;
  102.                         if(counta==3||counta==6)cout<<" ";
  103.                    }
  104.                    if(counta==9)counta=0;
  105.                    countb++;
  106.                    if(countb==3||countb==6)cout<<endl;
  107.                    cout<<endl;
  108.            }
  109.     }
  110.  
  111.  
y los archivos sudoku y config contienen:
sudoku.txt
Código:
0 0 0 0 4 3 0 0 6
0 0 0 0 0 0 4 8 0
2 4 8 0 0 0 0 0 7
3 2 0 0 0 6 8 0 9
1 8 0 3 0 0 6 0 2
6 0 0 0 0 0 7 3 5
0 7 0 0 0 0 5 6 0
5 0 2 6 0 0 0 0 3
8 6 0 0 5 0 0 0 0;

y
config.txt
Código:
1 1 1 2 2 2 3 3 3
1 1 1 2 2 2 3 3 3
1 1 1 2 2 2 3 3 3
4 4 4 5 5 5 6 6 6
4 4 4 5 5 5 6 6 6
4 4 4 5 5 5 6 6 6
7 7 7 8 8 8 9 9 9
7 7 7 8 8 8 9 9 9
7 7 7 8 8 8 9 9 9;


En línea

MIG80

Desconectado Desconectado

Mensajes: 38



Ver Perfil
Re: duda freopen
« Respuesta #1 en: 20 Julio 2010, 04:43 am »

bueno.. no se si freopen() se puede usar dos veces para hacer que la entrada venga desde un archivo..
Código
  1. freopen("sudoku.txt","r",stdin);
  2. ...
  3. freopen("config.txt","r",stdin);
  4.  
pero creo que el segundo freopen() no es necesario dado que se puede inicializar el arreglo con los valores deseados en lugar hacerlo durante la ejecucion del programa
Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. int matriz[9][9]={
  6. 1,1,1,2,2,2,3,3,3,
  7. 1,1,1,2,2,2,3,3,3,
  8. 4,4,4,5,5,5,6,6,6,
  9. 4,4,4,5,5,5,6,6,6,
  10. 4,4,4,5,5,5,6,6,6,
  11. 7,7,7,8,8,8,9,9,9,
  12. 7,7,7,8,8,8,9,9,9,
  13. 7,7,7,8,8,8,9,9,9
  14. };
  15.  
  16. int sudoku[9][9], seguros[9][9], posible=0, unicas=1;
  17. bool usado[10];
  18.  
  19. void imprimir();
  20. void unicas_soluciones();
  21. void comprobar(int a, int b);
  22.  
  23. int main()
  24. {...}
  25.  


« Última modificación: 20 Julio 2010, 04:54 am por czealt » En línea

Og.


Desconectado Desconectado

Mensajes: 822


Aprendiendo de la vida


Ver Perfil
Re: duda freopen
« Respuesta #2 en: 20 Julio 2010, 06:58 am »

Solo vi el codigo por arriba, el config.txt lo usas para saber en que cuadro esta el numero cierto?

yo haria esto:
Código
  1. bool* posibilidades(int i, int g)
  2. {
  3.    bool *p = new bool[9];
  4.    for(int x=0; x<9; x++)
  5.        p[x] = true;
  6.    for(int x=0; x<9; x++)
  7.    {
  8.        if(sudoku[x][g]!=0)
  9.            p[sudokuo[x][g]-1] = false;
  10.        if(sudoku[i][x]!=0)
  11.            p[sudoku[i][x]-1] = false;
  12.    }
  13.    int cuadro1, cuadro2;
  14.    if(i<=2) cuadro1 = 0;
  15.    else if(i<=5) cuadro1 = 3;
  16.    else cuadro1 = 6;
  17.    if(g<=2) cuadro2 = 0;
  18.    else if(g<=5) cuadro2 = 3;
  19.    else cuadro2 = 6;
  20.    for(int l=0; l<3; l++)
  21.        for(int n=0; n<3; n++)
  22.            if(sudoku[l+cuadro1][n+cuadro2])
  23.                p[sudoku[l+cuadro1][n+cuadro2]-1]=false;
  24.    return p;
  25. }

Esta función te regresara un arreglo de booleanos numerados del 0 al 8 que te dirán que ficha puede entrar.
Por ejemplo si te regresa: 000100011, significa que puedes meter un 4, 8 o 9.
A. no olvides liberar la memoria cuando la desocupes.

Saludos!

Edit: una duda, es la tarea de backtracing de padilla? (no me hagan caso si no son de Jalisco, tal ves estoy confundiéndome xD)
« Última modificación: 20 Julio 2010, 07:06 am por Og. » En línea

|-
MIG80

Desconectado Desconectado

Mensajes: 38



Ver Perfil
Re: duda freopen
« Respuesta #3 en: 20 Julio 2010, 09:15 am »

lo mismo.. pero mas rapido ::)
Código
  1. bool *posibilidades(int a,int b)
  2. {
  3.  const int fi=(a/3)*3,ci=(b/3)*3;
  4.  static bool p[10];
  5.  for(int z=0;z<10;z++)
  6.    p[z]=true;
  7.  for(int k=0;k<9;k++)
  8.  {
  9.    p[sudoku[a][k]]=p[sudoku[k][b]]=p[sudoku[fi+k/3][ci+k%3]]=false;
  10.  }
  11.  return &p[1];
  12. }
  13.  
la verificacion de si la casilla esta ocupada o no se hace fuera de la funcion:
Código
  1. ...
  2. if(sudoku[a][b]==0)
  3.  p=posibilidades(a,b);
  4.  
y ya no hace falta liberar la memoria ocupada por 'p' despues de cada llamada
Saludos  :)
« Última modificación: 20 Julio 2010, 09:44 am por czealt » En línea

Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: duda freopen
« Respuesta #4 en: 20 Julio 2010, 11:05 am »

Bueno, volviendo al tema principal!  :D

Citar
bueno, pues según lo que leí el freopen sirve para abrir un archivo y asignarlo para el flujo de datos de entrada o de salida, por ejemplo, yo lo estoy usando para llenar unas matrices en un programa que intenta resolver algun sudoku, y mi problema es que no se como cerrar el archivo, y como lo asigno para que de ahi vengan los datos de entrada, pues ya no puedo aplicar algo para que el usuario salga del programa sin matarlo.
y esa es mi duda, como cerrar un archivo o volver a que los datos de entrada entren por el teclado y no por el archivo.

Lo primero es saber que no hay una forma estandar de hacer lo que pides, tal vez algo rebuscado se pueda lograr, pero no exactamente lo que pides. Los aspectos subyacentes especificos de cada sistema hacen que sea imposible que el estandar pueda abarcarlos todos.

Dicho eso, la mejor opción dependerá mayormente del sistema en el que estés trabajando. Así que basicamente podes abstraer en una librería los algoritmos que necesites dependiendo de los sistemas en los cuales quieres que el programa funcione, o bien utilizar alguna librería multi-plataforma ya desarrollada y testeada (como Boost, por ejemplo).


Algo como esto:

Código
  1. freopen("CON","r",stdin);

probablemente te funcione siempre y cuando estés en un sistema Windows, y obviamente, que los streams estén asociados a la consola. Eso si, teniendo en claro que seria la peor forma de hacerlo, por la falta de portabilidad y porque este método puede ser propenso a errores en el caso que las redirecciones tiendan a aumentar de complejidad. 

También cabe aclarar que realmente no veo que sea necesario redirigir los streams en la idea que plantea el algoritmo. Seria bastante mas eficiente y flexible elaborar un modulo que se encargue de la lectura y el procesado de un formato de archivo, y en todo caso en cambios futuros solo necesitarías cambiar ese modulo

Para no extenderme mucho mas, lo primero seria que aclares en que sistema necesitas que funcione para poder guiarte adecuadamente. Si la respuesta es elaborar un algoritmo multi-plataforma, probablemente encuentres algún código hecho con Boost si buscas sobre redirecciones de streams en Google.

Saludos!
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines