Sie sind auf Seite 1von 20

Biblioteca estndar de C: Algunas funciones y trucos

Lectura de Input

fscanf(FILE *stream, const char *format, ...) Caractersticas: Retorna 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 lnea, 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

Se permite que el string de formato tenga caracteres al comienzo. En este caso,


la funci
on fscanf espera que estos aparezcan al comienzo del input. Si no es
as, no leera nada.
No recomendada para: En general no se recomienda usarla si importa leer
caracteres normalmente ignorados. En particular, no sirve para leer archivos lnea
por lnea y no sirve para hacer cualquier tipo de parseo.
Truco 1: Es posible obtener el n
umero de caracteres que fscanf ha ledo usando
el 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

Este es un ejemplo de ejecuci


on:
34 54 67
1
34
1
54
1
67
45
1
45

2
3
3
3

Truco 2: Es posible descartar el almacenamiento un dato exitosamente convertido


con 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) Caractersticas: Lee


una lnea completa desde el archivo stream, almacena el resultado en el string
s. Lee a lo mas size caracteres. Retorna s en caso de exito y NULL en caso de
error.
Advertencia: fgets lee tambien el fin de lnea \n.
Jorge Baier Aranda, PUC

int fgetc(FILE *stream) Caractersticas: Lee un caracter desde stream


como unsigned char convertido a int.
int ungetc(int c, FILE *stream) Caractersticas: Devuelve un caracter
hacia stream. S
olo se garantiza que se pueda devolver un caracter. No se puede
devolver EOF. Retorna el caracter devuelto o EOF en caso de error.
int feof(FILE *stream) Caractersticas: Retorna un valor no nulo si se ha
ledo el fin de archivo desde stream.

Manejo de Strings

char *strstr(const char *haystack, const char *needle) Caractersticas: Retorna un puntero al primer caracter de la primera ocurrencia del string
needle dentro del string heystack o NULL si no hay tal ocurrencia.
char *strpbrk(const char *s, const char *accept)
Jorge Baier Aranda, PUC

Caractersticas:
4

Retorna un puntero al caracter en s que esta presente en el string accept


o NULL si tal caracter no es encontrado.
char *strtok(char *s, const char *delim) Busca en s por tokens delimitados 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 se
encuentran mas tokens.
Cuando un token termina con un delimitador, el caracter delimitador es sobreescrito con un \0. Esto significa que el string original es alterado.
Dato curioso: En el manual de unix de esta funci
on aparece lo siguiente:
BUGS
Never 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 del


estilo /etc/passwd de Unix. Tiene un serio problema con los campos vacos...
Jorge Baier Aranda, PUC

#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 encontr
e 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

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


pcap:x:77:77::/var/arpwatch:/sbin/nologin

tiene el siguiente comportamiento:


login: rpcuser
passwd: x
user: 29
group: 29
name: RPC Service User
home: /var/lib/nfs
shell: /sbin/nologin
----------------------login: nfsnobody
passwd: x
user: 65534
group: 65534
name: Anonymous NFS User
home: /var/lib/nfs
shell: /sbin/nologin
----------------------No encontr
e todos los datos!
login: pcap
passwd: x
user: 77
group: 77
name: /var/arpwatch
home: /sbin/nologin
-----------------------

Jorge Baier Aranda, PUC

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 manera
muy directa.
Manejo de Strings

STL provee la clase string para manejo de strings.


Muchas operaciones (como concatenaci
on y reemplazo) tienen sus propios operadores.

Jorge Baier Aranda, PUC

El siguiente ejemplo muestra algunas de sus potencialidades.


#include <iostream>
#include <string>
using namespace std;
int main() {
string s1;
// inicializa un string vac
o
string 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 C
s1.insert(0,s2);
// s1 = "holatola cccccc"
string::size_type i = s1.find("cc"); // i=9
i = s2.length();
// i = 4
s3=s2.substr(1,3);
// s3="ola"
s1.replace(s1.find("tola"),4,","); // s1 = "hola, cccccc"
return 0;
}

Jorge Baier Aranda, PUC

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>
<list>
<deque>
<queue>
<stack>
<map>
<set>
<bitset>

arreglo unidimensional de T
lista doblemente ligada de T
cola de doble extremo de T
cola de T
pila de T
arreglo asociativo de T
conjunto de T
arreglo de bits T

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


algunos de estos contenedores.
Jorge Baier Aranda, PUC

10

Vectores
Los vectores son muy similares a los arreglos. De hecho, se permite acceder a la
enesima posici
on a traves de A[n].
Agregar elementos al final de un vector es muy eficiente (O(1)) pero eliminar o
agregar elementos en otra parte toma en general tiempo O(n), con n el n
umero
de elementos en el vector.
Las siguientes estan dentro de los metodos mas u
tiles de la clase vector:
M
etodo

Efecto/Retorno

begin()
end()
push_back(valor)
pop_back(variable)
insert(iterador,valor )
erase(iterador)
size()
empty()
[]

Retorna iterador apuntando al primer elemento


Retorna iterator apuntando despues del u
ltimo elemento
Agrega un elemento al final del vector
Destruye el elemento al final del vector
Inserta un nuevo elemento
Elimina un elemento (*)
N
umero de elementos
Verdadero si el vector esta vaco
Acceso directo

Jorge Baier Aranda, PUC

11

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

8469 16816 17146 18042 19577


-1 8469 17146 18042 19577

Jorge Baier Aranda, PUC

13

Lectura de Input en C++


En C++, la lectura de input se debiera realizar usando las funciones C++ para
lectura de archivo.
El operador >> aplicado sobre un objeto del tipo ifstream tiene un efecto similar
al de scanf (ignora separadores). Ejemplo:
#include <iostream>
#include <string>
...
string s;
cin >> s;

Para leer lneas completas, se usa el metodo getline. Ejemplo:


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

El siguiente programa lee lneas que contienen un string y luego un entero.


Jorge Baier Aranda, PUC

14

#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 est
andar
f.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 est
andar
while (1) {
*p >> s; *p >> n;
if (p->fail()) break;
cout <<"!"<< s << "!" << n << "!" << endl;
}
f.close();
return 0;
}

Jorge Baier Aranda, PUC

15

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() y
pop_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:
S
olo es posible agregar un elemento al final de la cola.
S
olo es posible extraer un elemento del principio de la cola.
Jorge Baier Aranda, PUC

16

Colas de Prioridades (priority queue)


Son similares a las colas. Sirven cuando es necesario tener un contenedor donde
s
olo extraer importa el elemento mas grande.
La operaci
on de eliminaci
on e inserci
on 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

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


nombre = nom;
prioridad = prio;
}
};
// Compara dos procesos
bool operator < (const Proceso &p1, const Proceso &p2) {
return p1.prioridad < p2.prioridad;
}
// Muestra un proceso en pantalla
ostream & 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

cout << endl;


return( EXIT_SUCCESS );
}

Y produce el siguiente output


Proceso:
Proceso:
Proceso:
Proceso:
Proceso:

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

Jorge Baier Aranda, PUC

19

Algoritmos
La STL provee una gran cantidad de algoritmos predefinidos cuando se incluye la
cabecera <numeric>.
Destacan los siguientes (generalmente usados en deques, listas y vectores):

Funci
on

Descripci
on

find()
replace_if()
reverse()
random_shuffle()
sort()
stable_sort()
binary_search()
generate()
unique()
lower_bound()
upper_bound()
merge()

Encuentra un elemento en una secuencia


Reemplaza los elementos que satisfacen una propiedad
Invierte el orden de los elementos propiedad
Reordena los elementos en forma aleatoria
Ordena los elementos
Ordena los elementos en forma estable
Busca un elemento en una secuencia ordenada
Reemplaza cada elemento con el resultado de una operacion sobre este.
Elimina elementos adyacentes que son iguales
Encuentra la cota inferior en una secuencia ordenada
Encuentra la cota superior en una secuencia ordenada
Mezcla dos secuencias ordenadas

Jorge Baier Aranda, PUC

20

Das könnte Ihnen auch gefallen