25 Haziran 2018 Pazartesi

scanf ailesi

Giri
scanf ailesi formatlı veri okumak için kullanılır. Aile fscanf(),scanf(),sscanf() metodlarından oluşur.

fscanf() bir dosyadan okuma yapar.
scanf() stdin'den okuma yapar.
sscanf() ise bir string'den okuma yapar.

fscanf yerine formatsız olarak tüm satırı okumak için C kütüphanesinde fgets veya C++ kütüphanesindeki std::getline() kullanılabilir.

İlk Scanf Kullanan Programlama Dili Nedir?
Cevap şöyle : Fortran: October 1956.

Scanf Ailesi Ne Döner
Eğer format belirteci yanlışsa, doldurulma davranışı tanımsızdır.
If a conversion specification is invalid, the behavior is undefined
Ancak scanf ailesi kaç tane değişkeni doldurduğunu döner. Buradan işlemin başarılı olup olmadığı anlaşılabilir.
Örnek
Şöyle yaparız.
FILE *f = ...;
char linha[255];

while(fscanf(f, " %s", &linha) = 1 )
{
  ...
}
Örnek
Şöyle yaparız. EOF genellikle -1 olarak tanımlıdır.
while (scanf("%d", &a) != EOF) {
  ...
}
Overflow
Scanf ailesi eğer taşma varsa tespit edemiyor deniliyor. Tam olarak ne kast ediliyor emin değilim.

Format Belirteçleri
scanset

Mantık olarak printf'teki precision'a benzer. İki türü vardır.
1. % karakterinden sonra sayı gelebilir. Bu durumda en fazla kaç karakter okuyacağımızı belirtiriz.
2. % karakterinden sonra * gelir. Bu durumda kaç karakter okuyacağımız belirsizdir. Hangi koşulu sağlayan karakterde duracağımızı belirtmemiz gerekir.
double - %lf
Şöyle yaparız.
double value;
fscanf(file, "%lf", &value);
string için scanset - % + sayı
Scanset sadece %s ile kullanılır. Belli bir karaktere kadar okumak içindir.
Örnek
Şöyle yaparız.
int a;
char b[255];
printf("Enter a number: ");
scanf("%254[^4]", &b);
Örnek
Elimizde şöyle satırlar olsun.
X1034Example
X1234Example2
Y2934Example3
Elimizde şöyle bir kod olsun.
int id; char label[64];
X + 4 rakam + en fazla 63 karakter için şöyle yaparız.
if (fgets(buffer, sizeof buffer, stdin)) {
  if (sscanf(*fp, "X%4d%63[^\n]", &id, label) == 2) {
    ...
  }
}
string için scanset - %+* belirteçleri
Bu belirteç bizi, düzenli ifade kullanmaktan koruyabilir. Belli bir karaktere kadar olan örüntüyü atlamamızı sağlar. Örnekte 45 sayısı çok kolay okunabiliyor.
std::string ex = "Example_45-3";
int num;
sscanf( ex.c_str(), "%*[^_]_%d", &num );
Başka örnekler.
//exclude only '\t' and '\n'
fscanf(file, "%[^\t\n]", buffer);
//include only alphanumeric characters and space
fscanf(file, "%[0-9A-Za-z ]", buffer);
//include all ASCII printable characters
fscanf(file, "%[ -~]", buffer);
Başka örnekler.
//* Skip all non printable control characters
fscanf(file, "%*[^ -~]");

//Read up to 100 printable characters so the buffer cannot overflow.
fscanf(file, "%100[ -~]", buffer);
%m format belirteci
Bu belirteç gerektiği kadar bellek ayrılmasını talep eder.
while(fscanf(fp,"%m[^\n]", &line) == 1) { ... }
%zu - size_t okumak için
size_t cinsinden okuma yapmayı sağlar.
size_t len = 0;
if (1 == sscanf(input, "%zu", &len))


Hiç yorum yok:

Yorum Gönder