Printf'de "%. * S" ne anlama geliyor?


Yanıtlar:


121

*Genişlik tanımlayıcısını / duyarlığını printf()biçim dizesine sabit kodlamak yerine, geçmek için bir yıldız işareti ( ) kullanabilirsiniz , ör.

void f(const char *str, int str_len)
{
  printf("%.*s\n", str_len, str);
}

4
str_lenArgümanın türüne int(veya yükseltilecek daha dar integral tipine) sahip olması gerektiği unutulmamalıdır int. Geçmesine bir hata olacağını long, size_tvb
MM

10
Bu kodun olası amacının, özellikle birlikte kullanıldığında %s, orijinal dizenin bir alt dizesini yazdırmak olduğunu belirtmek gerekir. Bu kullanım durumunda, strorijinal dizenin içinde bir yere işaret eder (muhtemelen başında) ve str_lenyazdırılması gereken alt dizenin uzunluğunu belirtir.
Sonic Atom

2
Bir uzunluk belirleyerek, boş sonlandırıcı içermeyen bir dizeyi yazdırmayı (veya sprintf) aşabiliriz, örneğin herhangi bir akıştan veya dosya tabanlı kaynaktan gelen bir dizge. Bu, yalnızca güzel baskılardan çok daha sık karşılaştığım kullanım durumudur.
Conrad B

23

Daha ayrıntılı burada .

tamsayı değeri veya *minimum alan genişliğini belirten. Sonuç, gerekirse boşluk karakterleriyle doldurulur (varsayılan olarak), sağa yaslandığında solda veya sola yaslanmışsa sağda. * Kullanılması durumunda, genişlik int türünde ek bir bağımsız değişken tarafından belirtilir. Bağımsız değişkenin değeri negatifse, belirtilen - bayrağı ve pozitif alan genişliği ile sonuçlanır. (Not: Bu, minimum genişliktir: Değer hiçbir zaman kesilmez.)

.ve ardından tamsayı veya * veya bu, dönüşümün doğruluğunu belirtmez. * Kullanılması durumunda, kesinlik int türünde ek bir bağımsız değişken tarafından belirtilir. Bu argümanın değeri negatifse, dikkate alınmaz. Ne bir sayı ne de * kullanılmazsa, hassasiyet sıfır olarak alınır. Kesinliğin kesin etkileri için aşağıdaki tabloya bakın.

Dolayısıyla, her iki dönüşüm özelliğini de denersek

#include <stdio.h>

int main() {
    int precision = 8;
    int biggerPrecision = 16;
    const char *greetings = "Hello world";

    printf("|%.8s|\n", greetings);
    printf("|%.*s|\n", precision , greetings);
    printf("|%16s|\n", greetings);
    printf("|%*s|\n", biggerPrecision , greetings);

    return 0;
}

çıktıyı alıyoruz:

|Hello wo|
|Hello wo|
|     Hello world|
|     Hello world|

12

Ben yukarıdaki kod doğrudur düşünmüyorum ama (bu açıklamasına göre printf()) .*araçlar

Genişlik, biçim dizesinde belirtilmez, ancak biçimlendirilmesi gereken bağımsız değişkenden önce gelen ek bir tamsayı değer bağımsız değişkeni olarak belirtilir. '

Bu nedenle, argüman olarak kabul edilebilir genişliğe sahip bir dizedir.


2
İntihal suçlamalarından kaçınabilmeniz için URL çapraz referansını ekledim. Tabii ki, doğru alıntı "diyor hassas " değil ... "yerine genişlik değil ...".
Jonathan Leffler

@MattMcNabb'ın belirttiği gibi, bu sayfaya yapılan her referans, " bir tamsayı değerinin " tam olarak int(veya onun bir alt kümesi) olduğunu vurgulamalıdır - sadece daha sezgisel size_tveya olası takma adları gibi herhangi bir integral değer değil std::string::size_type. Başvurulan sayfanın size_tdesteklenen tür belirticilerinden biri olarak bahsedildiği göz önüne alındığında, bu daha da kafa karıştırıcıdır .
Anton Samsonov

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.