Существует ли способ указать сколько символов строки для распечатывания использования printf ()?

Есть ли способ указать сколько символов строки для распечатывания (подобный десятичным разрядам в 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

109
задан Melebius 31 October 2017 в 07:35
поделиться

7 ответов

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

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 () определяет эти механизмы.

206
ответ дан 24 November 2019 в 03:21
поделиться
printf ("Here are the first 8 chars: %.8s\n", "A string that is more than 8 chars");

%8s задает минимальную ширину в 8 символов. Вы хотите усечь на 8, поэтому используйте %.8s.

Если вы хотите всегда печатать ровно 8 символов, вы можете использовать %8.8s

12
ответ дан 24 November 2019 в 03:21
поделиться

Используя 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;
11
ответ дан 24 November 2019 в 03:21
поделиться

Выведите первые четыре символа:

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

See this link for more information (check .precision -section)

4
ответ дан 24 November 2019 в 03:21
поделиться

Кроме того чтобы указать фиксированное количество символов, вы также можете использовать * , что означает, что 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'
10
ответ дан 24 November 2019 в 03:21
поделиться

В C ++ это просто.

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

РЕДАКТИРОВАТЬ: Также безопаснее использовать это со строковыми итераторами, чтобы не сбежать с конца. Я не уверен, что происходит с printf и слишком короткими строками, но я думаю, это может быть безопаснее.

4
ответ дан 24 November 2019 в 03:21
поделиться

Люди уже привели причины, по которым я обычно выручаю: старый (больше не применимый к большинству компиляторов) аргумент о том, чтобы не включать stdlib.h и использовать sizeof * p , чтобы убедиться, что типы и размеры всегда совпадают независимо от последующего обновления. Я хочу указать еще на один аргумент против кастинга. Он маленький, но я думаю, он применим.

C довольно слабо набран. Большинство преобразований безопасного типа происходит автоматически, а для большинства небезопасных требуется приведение. Рассмотрим:

int from_f(float f)
{
    return *(int *)&f;
}

Это опасный код. Это технически неопределенное поведение, хотя на практике оно будет делать то же самое почти на каждой платформе, на которой вы его запускаете. А актёрский состав помогает сказать вам "Этот код - ужасный взлом".

Подумайте:

int *p = (int *)malloc(sizeof(int) * 10);

Я вижу актёрский состав, и мне интересно: "Зачем это нужно? Где взлом? Это поднимает волосы на моей шее, что происходит что-то зло, когда на самом деле код совершенно безвреден.

Пока мы используем C, слепки (особенно слепки указателей) - это способ сказать: «Здесь происходит что-то злое и легко разрушаемое». Они могут достичь того, что вам нужно, но они указывают вам и будущим сопровождающим, что дети не в порядке.

Использование слепков на каждом маллоке уменьшает индикацию «взлома» при показании указателя. Это делает менее страшным видеть такие вещи, как * (int *) & f; .

Примечание: C и C++ - разные языки. C слабо типизируется, C++ более сильно типизируется. Слепки необходимы в C++, даже если они вообще не указывают на взлом, из-за (на мой скромный взгляд) излишне сильной системы типа C++. (Действительно, этот конкретный случай - единственное место, где, я думаю, система типа C++ «слишком сильна», но я не могу придумать место, где она «слишком слаба», что делает ее в целом слишком сильной для моих вкусов.)

Если вы беспокоитесь о совместимости C++, не стоит. Если вы пишете C, используйте компилятор C. Есть много действительно хороших, доступных для каждой платформы. Если по какой-то странной причине у вас есть для записи кода C, который компилируется чисто как C++, вы на самом деле не пишете C. Если вам нужно портировать C на C++, вы должны внести много изменений, чтобы сделать ваш код C более идиоматичным C++.

Если вы не можете сделать ничего из этого, ваш код не будет довольно независимо от того, что вы делаете, так что на самом деле не важно, как вы решите сделать в этот пункт. Мне нравится идея использования шаблонов для создания нового распределителя, который возвращает правильный тип, хотя это в основном просто переосмысление ключевого слова new .

-121--1713949-

В основном вы пишете инструмент дедупликации, где вы показываете обе записи на экране бок о бок с возможностью выбрать запись, которую вы хотите сохранить, но проверить отдельные данные из другой записи, чтобы сохранить также. Поскольку дедупликация очень отличается от базы данных к базе данных и сильно зависит от конкретной структуры таблицы и бизнес-правил (а также знания о том, на какие вещи нужно смотреть для того типа дедупликации вы делаете, так как они обычно показывают только самые важные таблицы отношений на экране), я никогда не видел тот, который не был построен в доме.

Но если вы хотите быстро просмотреть все данные, напишите запрос, который оставил соединения со всеми дочерними таблицами и отобразит все поля для обоих транзакций. Затем прочитайте свои результаты.

Что еще более важно, как вы в конечном итоге получили dup, если у вас есть бизнес-правило, которое требует, чтобы код транзакции был уникальным. Вы забыли, что все эти типы правил должны быть подкреплены базой данных, а не приложением? Почему на этом поле не было уникального индекса?

-121--2705496-

printf (..... «% .8s»)

3
ответ дан 24 November 2019 в 03:21
поделиться