Есть ли способ указать сколько символов строки для распечатывания (подобный десятичным разрядам в int
s)?
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
Основной способ:
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 ()
определяет эти механизмы.
printf ("Here are the first 8 chars: %.8s\n", "A string that is more than 8 chars");
%8s задает минимальную ширину в 8 символов. Вы хотите усечь на 8, поэтому используйте %.8s.
Если вы хотите всегда печатать ровно 8 символов, вы можете использовать %8.8s
Используя 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;
Выведите первые четыре символа:
printf("%. 4s\n", "A string that is more than 8 chars");
See this link for more information (check .precision -section)
Кроме того чтобы указать фиксированное количество символов, вы также можете использовать *
, что означает, что 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'
В C ++ это просто.
std::copy(someStr.c_str(), someStr.c_str()+n, std::ostream_iterator<char>(std::cout, ""));
РЕДАКТИРОВАТЬ: Также безопаснее использовать это со строковыми итераторами, чтобы не сбежать с конца. Я не уверен, что происходит с printf и слишком короткими строками, но я думаю, это может быть безопаснее.
Люди уже привели причины, по которым я обычно выручаю: старый (больше не применимый к большинству компиляторов) аргумент о том, чтобы не включать 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
.
В основном вы пишете инструмент дедупликации, где вы показываете обе записи на экране бок о бок с возможностью выбрать запись, которую вы хотите сохранить, но проверить отдельные данные из другой записи, чтобы сохранить также. Поскольку дедупликация очень отличается от базы данных к базе данных и сильно зависит от конкретной структуры таблицы и бизнес-правил (а также знания о том, на какие вещи нужно смотреть для того типа дедупликации вы делаете, так как они обычно показывают только самые важные таблицы отношений на экране), я никогда не видел тот, который не был построен в доме.
Но если вы хотите быстро просмотреть все данные, напишите запрос, который оставил соединения со всеми дочерними таблицами и отобразит все поля для обоих транзакций. Затем прочитайте свои результаты.
Что еще более важно, как вы в конечном итоге получили dup, если у вас есть бизнес-правило, которое требует, чтобы код транзакции был уникальным. Вы забыли, что все эти типы правил должны быть подкреплены базой данных, а не приложением? Почему на этом поле не было уникального индекса?
-121--2705496-printf (..... «% .8s»)