Чи є спосіб вказати, скільки символів рядка слід роздрукувати за допомогою printf ()?


127

Чи є спосіб вказати, скільки символів рядка слід роздрукувати (подібно до десяткових знаків у ints)?

printf ("Here are the first 8 chars: %s\n", "A string that is more than 8 chars");

Хочеться, щоб він надрукував: Here are the first 8 chars: A string

Відповіді:


226

Основний спосіб:

printf ("Here are the first 8 chars: %.8s\n", "A string that is more than 8 chars");

Інший, часто більш корисний спосіб:

printf ("Here are the first %d chars: %.*s\n", 8, 8, "A string that is more than 8 chars");

Тут ви вказуєте довжину як аргумент int для printf (), який трактує '*' у форматі як запит на отримання довжини з аргументу.

Ви також можете використовувати позначення:

printf ("Here are the first 8 chars: %*.*s\n",
        8, 8, "A string that is more than 8 chars");

Це також аналогічно позначенню "% 8.8s", але знову ж таки дозволяє вказати мінімальну та максимальну тривалість під час виконання - більш реалістично в такому сценарії, як:

printf("Data: %*.*s Other info: %d\n", minlen, maxlen, string, info);

Специфікація POSIX для printf()визначення цих механізмів.


2
До останнього прикладу: що робити, якщо скопійований рядок коротший за minlen?
шукач правди

4
Вихід буде пустим (зліва, якщо ви не додасте a -), щоб досягти всієї заданої довжини.
Джонатан Леффлер

13
printf ("Here are the first 8 chars: %.8s\n", "A string that is more than 8 chars");

% 8s вказуватиме мінімальну ширину 8 символів. Ви хочете усікати в 8, тому використовуйте% .8s.

Якщо ви хочете завжди друкувати рівно 8 символів, ви можете використовувати% 8.8s


13

Крім того, щоб вказати фіксовану кількість символів, ви також можете використовувати, *що означає, що printf приймає кількість символів з аргументу:

#include <stdio.h>

int main(int argc, char *argv[])
{
        const char hello[] = "Hello world";
        printf("message: '%.3s'\n", hello);
        printf("message: '%.*s'\n", 3, hello);
        printf("message: '%.*s'\n", 5, hello);
        return 0;
}

Друкує:

message: 'Hel'
message: 'Hel'
message: 'Hello'

11

Використовуючи printfви можете робити

printf("Here are the first 8 chars: %.8s\n", "A string that is more than 8 chars");

Якщо ви використовуєте C ++, ви можете досягти того ж результату, використовуючи STL:

using namespace std; // for clarity
string s("A string that is more than 8 chars");
cout << "Here are the first 8 chars: ";
copy(s.begin(), s.begin() + 8, ostream_iterator<char>(cout));
cout << endl;

Або менш ефективно:

cout << "Here are the first 8 chars: " <<
        string(s.begin(), s.begin() + 8) << endl;

1
Примітка: не використовуйте ostream_iterator<char>(cout)! Замість цього використовуйте ostreambuf_iterator<char>(cout)! Різниця в продуктивності повинна бути досить великою.
Дітмар Кюл

Шлях більш ефективно використовувати замість: std::cout.write(s.data(), 8). Або в сучасному C ++, std::cout << std::string_view{s.data(), 8}.
Artyer

4

Друк перших чотирьох символів:

printf("%.4s\n", "A string that is more than 8 chars");

Перегляньте це посилання для отримання додаткової інформації (перевірити. Точність-розділ)


4

В C ++ це легко.

std::copy(someStr.c_str(), someStr.c_str()+n, std::ostream_iterator<char>(std::cout, ""));

РЕДАКТУВАННЯ: Це також безпечніше використовувати це за допомогою ітераторів рядків, тому ви не біжите до кінця. Я не впевнений, що станеться з надто короткими printf та рядком, але я думаю, що це може бути безпечніше.


32
га, так, це "просто". C ++ завжди виглядає як автомобільна аварія.
Президент Джеймс К. Полк

ви все ще можете зробити printf () в c ++ :)
StasM

6
Я думаю, що це був сарказм. std::cout << someStr.substr(0,8);набагато очевидніша.
MSalters

2
@MSalters Ви повинні опублікувати це як відповідь.
Джонатан Мі


1

У C ++ я це роблю так:

char *buffer = "My house is nice";
string showMsgStr(buffer, buffer + 5);
std::cout << showMsgStr << std::endl;

Зверніть увагу, це не є безпечним, оскільки при передачі другого аргументу я можу вийти за рамки розміру рядка і створити порушення доступу до пам'яті. Ви повинні здійснити власну перевірку, щоб уникнути цього.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.