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

 

 


Tema destacado: Recopilación Tutoriales y Manuales Hacking, Seguridad, Privacidad, Hardware, etc


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Leer de la entrada estandar linea por linea
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Leer de la entrada estandar linea por linea  (Leído 11,701 veces)
Delraich

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Leer de la entrada estandar linea por linea
« en: 5 Julio 2010, 23:57 pm »

Primero q nada hola a todos, empece hace poco a programar en C.. Lo q mas me interesa es programar algoritmos de matematica discreta, y tengo problemas con uno q calcula MaxFlow en un grafo.. con el algoritmo en si no, sino con la entrada estandar.. Quiero q lea desde la entrada estandar, cosas de la siguiente manera:
a b c
donde a, b y c son enteros... Pero quiero q lea mientras una linea sea de ese tipo.. cuando llega algo q no es de ese formato, deberia dejar de leer en la entrada estandar.. entonces para q quede claro, deberia poder poner por ejemplo:
1 2 3
3 2 5
4 5 2
3

En este ejemplo, quiero q tome el 1 2 3, el 3 2 5, el 4 5 2 y q deje de leer cuando vea q la 4ta linea tiene un solo numero...

Otro ejemplo seria
1 2 3
4 5 6
2 4 5 6

Aqui deberia leer 2 lineas, y cortar cuando llega la 3ra porq tiene un entero de mas..
Y tambien tiene q cortar si llega algo asi:

1 2 3
3 4 5
hola

Lee 2 lineas, y luego corta porq llega algo q no tiene nada q ver con el formato...

Probe con scanf pero no logro q corte cuando la linea tiene caracteres de menos.. ya q el scanf se queda esperando a q se completen sus parametros...\
Por otro lado tampoco logro q corte cuando llegan caracteres de mas, ya q los guarda en el buffer para el siguiente scanf...

Asi q si me pueden ayudar, desde ya les agradezco


En línea

nicolas_cof


Desconectado Desconectado

Mensajes: 348


Into the Wild


Ver Perfil WWW
Re: Leer de la entrada estandar linea por linea
« Respuesta #1 en: 6 Julio 2010, 00:45 am »

Delraich, bienvenido! te recomendaria leer las Reglas del subforo

Si pones algo del avance que llevas hecho seria mas facil para nosotros poder ayudarte.

Te invito a que pases por estos temas...

https://foro.elhacker.net/programacion_cc/librospapers_c_and_c-t296234.0.html

https://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html

Salu10.


En línea

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

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Leer de la entrada estandar linea por linea
« Respuesta #2 en: 6 Julio 2010, 00:46 am »

Podrías hacer un arreglo de cadenas e ir leyendo linea a linea, luego convertir los datos relevantes para poder operarlos. Podrías también leer una cadena con toda la expresión, para luego poder tomar los datos relevantes de dicha expresión, convertirlos y operarlos.

Pon el código que llevas hecho a ver si podemos partir de ahí para ayudarte.

Saludos
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
ghastlyX
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.900



Ver Perfil
Re: Leer de la entrada estandar linea por linea
« Respuesta #3 en: 6 Julio 2010, 00:56 am »

Puedes leer una línea entera usando
Código
  1. getline(cin,s);
Donde s es una string.

Luego para parsear la entrada, si sabes que siempre serán números, puedes usar stringstream e ir leyendo desde s y añadiendo en un vector los números. Si no, deberías picar alguna función que compruebe que si es número o no.

En referencia al algoritmo, ¿cuál usas para calcular el Maxflow?
En línea

Delraich

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: Leer de la entrada estandar linea por linea
« Respuesta #4 en: 6 Julio 2010, 01:03 am »

Antes q nada, muchas gracias por responder tan rapido...

El programa la verdad es bastante extenso, sobre todo la parte del algoritmo en si.. pero la parte q lee desde la entrada estandar seria algo asi :

Ya cree la estructura donde voy a guardar el network (grafo).. y ahora tengo q agregar lado por lado... esta funcion está en un ciclo.. el ciclo corta cuando el valor de esta funcion es 0.. por eso, esta funcion debe devolver 1 mientras la entrada estandar sea del formato q quiero, y 0 cuando no sea..
La funcion CargarLado se encarga de tomar los 3 enteros (q serian vertice 1 del lado, vertice 2 del lado y capacidad de ese lado) y los introduce en la esctructura del grafo.. si puede cargarlos bien, devuelve 1.. sino, devuelve 0.. El problema aca es q cuando introduzco algo por entrada estandar q tiene caracteres, pero menos de 3 o mas de 3, el programa no corta.. sino q se queda esperando.. yo necesitaria que tome la linea entera como dice Littlehorse, pero la verdad no se como hacerlo

Código
  1. int LeerLado (EstadoNetwork n) {
  2.  
  3.    res = scanf(" %u %u %u", &c1, &c2, &c3);
  4.  
  5.  if (res == 3)
  6.  {
  7.    res = CargarLado(n->network,c1,c2,c3);
  8.  }
  9.  else
  10.  {
  11.    res = 0;
  12.  }
  13.  return res;
  14. }
  15.  

Recien leo la respuesta de ghastlyx, voy a intentar hacerlo asi, pasa q no siempre van a ser numeros, asi q voy a tener q primero ver si son numeros, y si lo son ver si son la cantidad q necesito..
Estoy implementando el algoritmo de Dinic, con el paso bloqueante tambien de dinic..
Luego quizas intente wave, pero necesito poder ingresar los datos del grafo bien primero

En línea

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

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Leer de la entrada estandar linea por linea
« Respuesta #5 en: 6 Julio 2010, 01:06 am »

El problema es que lo te menciono ghastlyX  es C++, y según mencionas vos en el post inicial, estas codificando el algoritmo en C.

Declara una cadena, y léela con fgets, luego puedes parsear los datos y operarlos previa validación.

Saludos
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
ghastlyX
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.900



Ver Perfil
Re: Leer de la entrada estandar linea por linea
« Respuesta #6 en: 6 Julio 2010, 01:14 am »

No me había fijado que había puesto C, sin STL lo que he dicho como que no xDD.

Por si te sirve de ayuda, te dejo un código del algoritmo de Dinic que tenía hecho, sigue el formato de entrada y salida de este problema:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=10&page=show_problem&problem=761

Código
  1. /****************************************************************************************/
  2. /* Algoritmo Dinic (usa blocking flows en lugar de caminos aumentativos) Coste: O(V^2E) */
  3. /****************************************************************************************/
  4.  
  5. #include <iostream>
  6. #include <string.h>
  7. using namespace std;
  8.  
  9. //Cambiar constantes si es necesario
  10. #define NODOS 100
  11. const int INF = 1000000000;
  12.  
  13. int adj[NODOS][NODOS], deg[NODOS], cap[NODOS][NODOS], padre[NODOS], f[NODOS][NODOS], MC[NODOS], visto[NODOS];
  14. int n, m; // n = |V|, m = |E|
  15.  
  16. int Q[NODOS]; //cola
  17. int ebp, esp;
  18.  
  19. bool bfs(int s, int t) {
  20.    esp = ebp = 0;
  21.    memset(padre, -1, sizeof(padre));
  22.    memset(visto, 0, sizeof(visto));
  23.    visto[s] = 1;
  24.    padre[s] = -2;
  25.    Q[esp++] = s;
  26.    while (ebp != esp) {
  27.        int u = Q[ebp++];
  28.        for (int i = 0; i < deg[u]; ++i) {
  29.            int v = adj[u][i];
  30.            if (cap[u][v] - f[u][v] > 0 and not visto[v]) {
  31.                visto[v] = 1;
  32.                padre[v] = u;
  33.                Q[esp++] = v;
  34.            }
  35.        }
  36.    }
  37.    return visto[t];
  38. }
  39.  
  40. void mincut(int s) {
  41.    ebp = esp = 0;
  42.    Q[esp++] = s;
  43.    MC[s] = 1;
  44.    while (ebp != esp) {
  45.        int u = Q[ebp++];
  46.        for (int i = 0; i < deg[u]; ++i) {
  47.            int v = adj[u][i];
  48.            if (cap[u][v] - f[u][v] > 0 and not MC[v]) {
  49.                MC[v] = 1;
  50.                Q[esp++] = v;
  51.            }
  52.        }
  53.    }
  54. }
  55.  
  56. int maxflow(int s, int t) {
  57.    int flow = 0;
  58.    memset(MC, 0, sizeof(MC));
  59.    memset(f, 0, sizeof(f));
  60.    while (bfs(s, t)) {
  61.        for (int i = 0; i < n; ++i) {
  62.            if (cap[i][t] - f[i][t] > 0 and padre[i] != -1) {
  63.                int bot = cap[i][t] - f[i][t];
  64.                for (int v = i, u = padre[i]; u >= 0; v = u, u = padre[u])
  65.                    bot = min(bot, cap[u][v] - f[u][v]);
  66.                if (bot == 0) continue;
  67.                f[i][t] += bot;
  68.                f[t][i] -= bot;
  69.                for (int v = i, u = padre[i]; u >= 0; v = u, u = padre[u]) {
  70.                    f[u][v] += bot;
  71.                    f[v][u] -= bot;
  72.                }
  73.                flow += bot;
  74.            }
  75.        }
  76.    }
  77.    mincut(s); //MC[u] == 1 <=> u esta en la particion de s
  78.    return flow;
  79. }
  80.  
  81. int main() {
  82.    int net = 1;
  83.    while (cin >> n and n > 0) {
  84.        memset(deg, 0, sizeof(deg));
  85.        memset(cap, 0, sizeof(cap));
  86.        int s, t;
  87.        cin >> s >> t >> m;
  88.        s--; t--;
  89.        for (int i = 0; i < m; ++i) {
  90.            int a, b, c;
  91.            cin >> a >> b >> c;
  92.            --a; --b;
  93.            if (cap[a][b] == 0) {
  94.                adj[a][deg[a]++] = b;
  95.                adj[b][deg[b]++] = a;
  96.            }
  97.            cap[a][b] += c;
  98.            cap[b][a] += c;
  99.        }
  100.        cout << "Network " << net++ << endl;
  101.        cout << "The bandwidth is " << maxflow(s,t) << "." << endl << endl;
  102.    }
  103. }
En línea

do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: Leer de la entrada estandar linea por linea
« Respuesta #7 en: 6 Julio 2010, 01:31 am »

¡Buenas!

para poder leer linea por linea puedes declarar una vector de caracteres de dimension "algo grande", y leerlo con fgtes:
Código
  1. #define LINEA_MAX 256
  2.  
  3. char linea[LINEA_MAX];
  4.  
  5. /* leemos mientras quede informacion -> mientras linea[strlen(linea)]!='\n'
  6. ya que fgets obtiene informacion hasta (MAX_LINEA - 1) o hasta que encuentra un salto de
  7. linea (lo almacena como ultimo caracter de la cadena) o hasta que encuentra un EOF */
  8. do{
  9.    fgets(linea,LINEA_MAX,stdin);
  10.    /* y ahora con la informacion haces lo que quieras.
  11.     RECOMENDACION: usa strtok para obtener las distintas partes separadas por espacios */
  12. }while(linea[strlen(linea) - 1] != '\n'); /* Al ser '\n' el ultimo caracter, ya no queda nada en la entrada */
  13.  

El resto te lo dejo a ti. Tendras que estudiar las funciones de manejo de cadenas de stringh, de stdlibh, y seguramente tambien las de stdio.h.

¡Saludos!
« Última modificación: 9 Julio 2010, 13:48 pm por do-while » En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
Delraich

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: Leer de la entrada estandar linea por linea
« Respuesta #8 en: 6 Julio 2010, 01:38 am »

De nuevo gracias por la ayuda, ya me voy a tomar un tiempo y leer el algoritmo q posteaste ghasltyx, ahora voy a intentar tomar linea por linea como me recomendaron, y ver como parseo la info... luego les cuento q tal me fue
En línea

MIG80

Desconectado Desconectado

Mensajes: 38



Ver Perfil
Re: Leer de la entrada estandar linea por linea
« Respuesta #9 en: 6 Julio 2010, 01:54 am »

Bueno...talvez esto te solucione el problema con la entrada...

Código:
int leer3ent(int *c1,int *c2,int *c3)
{
  int res;
  char remanente[1000],lineaentrada[1000];
  
  fgets(lineaentrada,1000,stdin);
  fflush(stdin);
  res=sscanf(lineaentrada,"%u %u %u%s",c1,c2,c3,remanente);
  return (res==3)?1:0;
}

int LeerLado(EstadoNetwork n)
{
  res=leer3ent(&c1,&c2,&c3);
  if(res)
    res=CargarLado(n->network,c1,c2,c3);
  return res;
}

Saludos.
« Última modificación: 6 Julio 2010, 02:00 am por czealt » En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Duda Leer Linea por Linea de Un textBox
Programación Visual Basic
NsTeam 2 7,467 Último mensaje 1 Diciembre 2010, 02:58 am
por Stelio Kontos
[Ayuda] Leer linea de un fichero en Vb.Net
.NET (C#, VB.NET, ASP)
TMarmol 4 4,709 Último mensaje 19 Octubre 2013, 17:12 pm
por TMarmol
Extraer texto de textarea linea por linea
Programación General
alcipri 6 9,513 Último mensaje 24 Octubre 2014, 13:29 pm
por alcipri
Lectura de Línea a Línea de un archivo de números enteros en C++
Programación C/C++
julian21931500 7 9,830 Último mensaje 25 Febrero 2015, 04:11 am
por julian21931500
leer un array por entrada estandar (cmd)
Scripting
dijsktra 3 3,022 Último mensaje 1 Diciembre 2019, 04:29 am
por EdePC
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines