libreria std

20
Biblioteca estándar de C: Algunas funciones y trucos Lectura de Input fscanf(FILE *stream, const char *format, ...) Caracter´ ısticas: Retor- na el n´ umero de ´ ıtemes asignado (puede ser menor que el suplementado). Retorna EOF si se ley´ o el fin de archivo. Ignora todo tipo de separadores (espacios en blanco, fines de l´ ınea, tabulaciones). Recomendada para: leer n´ umeros, palabras (una por una), hacer parseos simples. Ejemplos de buen uso: fscanf(f,"%s%d",str,&x); /* para leer un string seguido de un entero sin importar que hay entremedio */ Uso no recomendable: fscanf(f,"numero: %d",&x);/* para leer n´ umero seguido de la palabra "numero:" (peligroso) */ Jorge Baier Aranda, PUC 1

Upload: aldo-federico-avalos

Post on 11-Jul-2016

215 views

Category:

Documents


1 download

DESCRIPTION

Librebia en C

TRANSCRIPT

Page 1: Libreria STD

Biblioteca estándar de C: Algunas funciones y trucos

Lectura de Input

fscanf(FILE *stream, const char *format, ...) Caracterısticas: Retor-na el numero de ıtemes asignado (puede ser menor que el suplementado). RetornaEOF si se leyo el fin de archivo. Ignora todo tipo de separadores (espacios enblanco, fines de lınea, tabulaciones).

Recomendada para: leer numeros, palabras (una por una), hacer parseos simples.

Ejemplos de buen uso:

fscanf(f,"%s%d",str,&x); /* para leer un string seguido de un enterosin importar que hay entremedio */

Uso no recomendable:

fscanf(f,"numero: %d",&x);/* para leer numero seguido de la palabra"numero:" (peligroso) */

Jorge Baier Aranda, PUC 1

Page 2: Libreria STD

Se permite que el string de formato tenga caracteres al comienzo. En este caso,la funcion fscanf espera que estos aparezcan al comienzo del input. Si no esası, no leera nada.

No recomendada para: En general no se recomienda usarla si importa leercaracteres normalmente ignorados. En particular, no sirve para leer archivos lıneapor lınea y no sirve para hacer cualquier tipo de “parseo”.

Truco 1: Es posible obtener el numero de caracteres que fscanf ha leıdo usandoel caracter de formato n. En el siguiente programa se usa dicho parametro.

#include <stdio.h>

int main() {char c;int x,i,r,cant;

while (!feof(stdin)) {r=fscanf(stdin,"%d%n",&x,&cant);if (r) printf("%d\t%d\t%d\n",r,x,cant);else break;

}return 0;

Jorge Baier Aranda, PUC 2

Page 3: Libreria STD

}

Este es un ejemplo de ejecucion:

34 54 671 34 21 54 31 67 3451 45 3

Truco 2: Es posible descartar el almacenamiento un dato exitosamente convertidocon fscanf. Esto se hace anteponiendo un * al caracter de formato. Ejemplo:

fscanf(stdin,"%*s%d%n",&x); /* solo interesa leer el entero */

char *fgets(char *s, int size, FILE *stream) Caracterısticas: Leeuna lınea completa desde el archivo stream, almacena el resultado en el strings. Lee a lo mas size caracteres. Retorna s en caso de exito y NULL en caso deerror.

Advertencia: fgets lee tambien el fin de lınea \n.

Jorge Baier Aranda, PUC 3

Page 4: Libreria STD

int fgetc(FILE *stream) Caracterısticas: Lee un caracter desde streamcomo unsigned char convertido a int.

int ungetc(int c, FILE *stream) Caracterısticas: Devuelve un caracterhacia stream. Solo se garantiza que se pueda devolver un caracter. No se puededevolver EOF. Retorna el caracter devuelto o EOF en caso de error.

int feof(FILE *stream) Caracterısticas: Retorna un valor no nulo si se haleıdo el fin de archivo desde stream.

Manejo de Strings

char *strstr(const char *haystack, const char *needle) Caracterısti-cas: Retorna un puntero al primer caracter de la primera ocurrencia del stringneedle dentro del string heystack o NULL si no hay tal ocurrencia.

char *strpbrk(const char *s, const char *accept) Caracterısticas:

Jorge Baier Aranda, PUC 4

Page 5: Libreria STD

Retorna un puntero al caracter en s que esta presente en el string accepto NULL si tal caracter no es encontrado.

char *strtok(char *s, const char *delim) Busca en s por tokens deli-mitados por caracteres en delim.

El primer llamado a strtok debe tener a s como primer argumento; los siguientes,NULL. Cada llamado retorna un puntero al siguiente token o NULL cuando no seencuentran mas tokens.

Cuando un token termina con un delimitador, el caracter delimitador es sobrees-crito con un \0. Esto significa que el string original es alterado.

Dato curioso: En el manual de unix de esta funcion aparece lo siguiente:

BUGSNever use these functions. If you do, note that:

These functions modify their first argument.These functions cannot be used on constant strings.The identity of the delimiting character is lost.

Ejemplo de Uso: El siguiente programa encuentra los campos en un archivo delestilo /etc/passwd de Unix. Tiene un serio problema con los campos vacıos...

Jorge Baier Aranda, PUC 5

Page 6: Libreria STD

#include <stdio.h>#include <string.h>

#define MAX 1024#define SEP "-----------------------"

int main() {FILE *fp;char buf[MAX],datos[7][MAX];char *ptr;int i;fp=fopen("passwd","r");while (fgets(buf,MAX,fp)!=NULL) {

ptr=strtok(buf,":\n");for(i=0;ptr;ptr=strtok(NULL,":\n"),i++)

strcpy(datos[i],ptr);

if (i<7) printf("No encontre todos los datos!\n");printf("login: %s\npasswd: %s\nuser: %s\ngroup: %s\nname: %s\nhome: %s\nshell: %s\n%s\n",

datos[0],datos[1],datos[2],datos[3],datos[4],datos[5],datos[6],SEP);

}fclose(fp);return 0;

}

Con el archivo:

rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin

Jorge Baier Aranda, PUC 6

Page 7: Libreria STD

nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologinpcap:x:77:77::/var/arpwatch:/sbin/nologin

tiene el siguiente comportamiento:

login: rpcuserpasswd: xuser: 29group: 29name: RPC Service Userhome: /var/lib/nfsshell: /sbin/nologin-----------------------login: nfsnobodypasswd: xuser: 65534group: 65534name: Anonymous NFS Userhome: /var/lib/nfsshell: /sbin/nologin-----------------------No encontre todos los datos!login: pcappasswd: xuser: 77group: 77name: /var/arpwatchhome: /sbin/nologin-----------------------

Jorge Baier Aranda, PUC 7

Page 8: Libreria STD

STL: Standard Template Library

STL es uno de los elementos mas interesantes de C++. Permite usar strings,algoritmos pre-definidos y contenedores (vectores, colas, stacks, etc.) de maneramuy directa.

Manejo de Strings

STL provee la clase string para manejo de strings.

Muchas operaciones (como concatenacion y reemplazo) tienen sus propios ope-radores.

Jorge Baier Aranda, PUC 8

Page 9: Libreria STD

El siguiente ejemplo muestra algunas de sus potencialidades.

#include <iostream>#include <string>

using namespace std;

int main() {string s1; // inicializa un string vacıostring s2="hola"; // inicializa string en "hola";string s3(6,’c’); // string s3 = "cccccc";s1 = s2 + " " + s3; // s1 = "hola cccccc";cout << ((s1==s2)? 1 : 0) << endl; // imprime "0", se puede usar >, < , >=, etc.s1[0] = ’t’; // s1 = "tola cccccc";printf("%s\n",s1.c_str()); // compatibilidad con strings de Cs1.insert(0,s2); // s1 = "holatola cccccc"string::size_type i = s1.find("cc"); // i=9i = s2.length(); // i = 4s3=s2.substr(1,3); // s3="ola"s1.replace(s1.find("tola"),4,","); // s1 = "hola, cccccc"return 0;

}

Jorge Baier Aranda, PUC 9

Page 10: Libreria STD

Contenedores en STL

Un contenedor objeto que permite almacenar otros objetos.

Existen contenedores basados en estructuras de datos conocidas.

Pueden almacenar distintos tipos de datos pues estan definidos como templates.

Estos son los contenedores definidos en STL:

Cabecera Contenedor

<vector> arreglo unidimensional de T

<list> lista doblemente ligada de T

<deque> cola de doble extremo de T

<queue> cola de T

<stack> pila de T

<map> arreglo asociativo de T

<set> conjunto de T

<bitset> arreglo de bits T

El contenedor priority_queue se declara en <queue>. Veremos el uso dealgunos de estos contenedores.

Jorge Baier Aranda, PUC 10

Page 11: Libreria STD

Vectores

Los vectores son muy similares a los arreglos. De hecho, se permite acceder a laenesima posicion a traves de A[n].

Agregar elementos al final de un vector es muy eficiente (O(1)) pero eliminar oagregar elementos en otra parte toma en general tiempo O(n), con n el numerode elementos en el vector.

Las siguientes estan dentro de los metodos mas utiles de la clase vector:

Metodo Efecto/Retorno

begin() Retorna iterador apuntando al primer elemento

end() Retorna iterator apuntando despues del ultimo elemento

push_back(valor) Agrega un elemento al final del vector

pop_back(variable) Destruye el elemento al final del vector

insert(iterador,valor ) Inserta un nuevo elemento

erase(iterador) Elimina un elemento (*)

size() Numero de elementos

empty() Verdadero si el vector esta vacıo

[] Acceso directo

Jorge Baier Aranda, PUC 11

Page 12: Libreria STD

El siguiente ejemplo muestra el uso de algunas funciones.

#include <iostream>#include <vector>#include <cstdlib>

using namespace std;

void muestra(vector<int> &v) {for (vector<int>::iterator viter=v.begin(); viter!=v.end(); ++viter)

cout << *viter << " "; cout << endl;}

int main() {vector<int> v;

for (int i=0; i<5; i++) {v.push_back(rand()/100000);

}muestra(v);sort(v.begin(), v.end() );muestra(v);v.erase(v.begin()+1);v.insert(v.begin(),-1);muestra(v);return( EXIT_SUCCESS );

}

El siguiente es el resultado que produce:

18042 8469 16816 17146 19577

Jorge Baier Aranda, PUC 12

Page 13: Libreria STD

8469 16816 17146 18042 19577-1 8469 17146 18042 19577

Jorge Baier Aranda, PUC 13

Page 14: Libreria STD

Lectura de Input en C++

En C++, la lectura de input se debiera realizar usando las funciones C++ paralectura de archivo.

El operador >> aplicado sobre un objeto del tipo ifstream tiene un efecto similaral de scanf (ignora separadores). Ejemplo:

#include <iostream>#include <string>

...string s;cin >> s;

Para leer lıneas completas, se usa el metodo getline. Ejemplo:

string s;getline(cin,s,’\n’);

El siguiente programa lee lıneas que contienen un string y luego un entero.

Jorge Baier Aranda, PUC 14

Page 15: Libreria STD

#include <iostream>#include <fstream>#include <string>

using namespace std;

int main() {string s,s2;int n;ifstream f;istream *p;

// comentar siguientes lıneas para leer de entrada estandarf.open("hola.txt");if (f.fail()) {

perror("no se puede abrir el archivo");exit(1);

}p = &f;//p = &cin; // descomentar para leer de la entrada estandarwhile (1) {

*p >> s; *p >> n;if (p->fail()) break;cout <<"!"<< s << "!" << n << "!" << endl;

}f.close();return 0;

}

Jorge Baier Aranda, PUC 15

Page 16: Libreria STD

Colas con acceso doble (deque)

Son similares a los vectores, pero:

• Agregar/eliminar al principio y al final es O(1). El metodo push_front() ypop_front() permite operar al principio de la lista.

Listas (list)

Son similares a los deques, pero:

• No es posible tener acceso directo al enesimo elemento.• Eliminar un elemento que no esta al final ni al principio es O(1).

Colas (queue)

Son similares a las listas, pero:

• Solo es posible agregar un elemento al final de la cola.• Solo es posible extraer un elemento del principio de la cola.

Jorge Baier Aranda, PUC 16

Page 17: Libreria STD

Colas de Prioridades (priority queue)

Son similares a las colas. Sirven cuando es necesario tener un contenedor dondesolo extraer importa el elemento mas grande.

La operacion de eliminacion e insercion es O(log n). (Se usan los metodos push()y pop() respectivamente.)

Conocer el elemento mayor es O(1). (Se usa el metodo top())

El siguiente es un ejemplo:

// C++ STL Headers#include <iostream>#include <queue>#include <string>

using namespace std;

class Proceso {private:

unsigned int prioridad;string nombre;

public:friend ostream& operator << ( ostream& os, const Proceso &task );friend bool operator < (const Proceso &p1, const Proceso &p2);

Jorge Baier Aranda, PUC 17

Page 18: Libreria STD

Proceso(const char *nom = "", unsigned int prio = 0 ){nombre = nom;prioridad = prio;

}};

// Compara dos procesosbool operator < (const Proceso &p1, const Proceso &p2) {return p1.prioridad < p2.prioridad;

}// Muestra un proceso en pantallaostream & operator<<( ostream &os, const Proceso &task ){os << "Proceso: " << task.nombre << "\tPrioridad: " << task.prioridad;return os;

}

int main( int argc, char *argv[] ){

int i;priority_queue<Proceso> task_queue;

Proceso tasks[] = { Proceso("JORGE"),Proceso("INIT",6), Proceso("Swapper",16),Proceso("LPD",8) , Proceso("HTTPD",8) };

for ( i = 0; i < sizeof(tasks)/sizeof(tasks[0]) ; i++ )task_queue.push( tasks[i] );

while ( !task_queue.empty() ) {cout << task_queue.top() << endl;task_queue.pop();

}

Jorge Baier Aranda, PUC 18

Page 19: Libreria STD

cout << endl;

return( EXIT_SUCCESS );}

Y produce el siguiente output

Proceso: Swapper Prioridad: 16Proceso: LPD Prioridad: 8Proceso: HTTPD Prioridad: 8Proceso: INIT Prioridad: 6Proceso: JORGE Prioridad: 0

Jorge Baier Aranda, PUC 19

Page 20: Libreria STD

Algoritmos

La STL provee una gran cantidad de algoritmos predefinidos cuando se incluye lacabecera <numeric>.

Destacan los siguientes (generalmente usados en deques, listas y vectores):

Funcion Descripcion

find() Encuentra un elemento en una secuencia

replace_if() Reemplaza los elementos que satisfacen una propiedad

reverse() Invierte el orden de los elementos propiedad

random_shuffle() Reordena los elementos en forma aleatoria

sort() Ordena los elementos

stable_sort() Ordena los elementos en forma estable

binary_search() Busca un elemento en una secuencia ordenada

generate() Reemplaza cada elemento con el resultado de una operacion sobre este.

unique() Elimina elementos adyacentes que son iguales

lower_bound() Encuentra la cota inferior en una secuencia ordenada

upper_bound() Encuentra la cota superior en una secuencia ordenada

merge() Mezcla dos secuencias ordenadas

Jorge Baier Aranda, PUC 20