Як повторити символ за допомогою printf?


79

Я хотів би зробити щось на зразок printf("?", count, char)повторення символу countразів.

Який правильний рядок формату для цього?

EDIT: Так, очевидно, що я міг би зателефонувати printf()у циклі, але саме цього я хотів уникнути.


2
Скільки ви мали на увазі?
WhozCraig

4
Невідомість підрахунку під час компіляції не є перешкодою для написання циклу.
Кіт Томпсон,

Ваше запитання досить зрозуміле (і справжня відповідь полягає в тому, що не існує printfформату, який робить те, що ви хочете), але ваші коментарі залишають мене невпевненим у тому, що ви запитуєте. Ви говорите про рядок формату та аргументи, які передаються у вашу функцію. Про яку функцію ви запитуєте? Здається, є речі, про які ви нам не кажете
Кіт Томпсон,

@KeithThompson Я написав обгортку навколо 'printf', тому ці аргументи були такими ж, як і для оригіналу, вибачте за плутанину. І я повинен був описати причину необхідності цього краще, ти маєш рацію.
Muis

Боюсь, я досі не маю чіткого уявлення про те, що ти намагаєшся зробити, або (не ображаючись на @synthesizerpatel), чому ти прийняв відповідь, яку ти зробив, яка не була задумана як серйозне рішення.
Кіт Томпсон,

Відповіді:


63

Коротка відповідь - так, довга відповідь: не так, як ти хочеш.

Ви можете використовувати форму% * printf , яка приймає змінну ширину. І, якщо для друку використовується значення «0», поєднане з вирівняним праворуч текстом, який зліва дорівнює нулю.

виробляє:

Засунувши язик у щоку, я пропоную цей маленький фрагмент коду з шоу жахів.

Іноді вам просто потрібно робити щось погано, щоб пам’ятати, чому ви так стараєтесь решту часу.


3
Я чітко не пам’ятаю, про що думав, але у вашому коді верхня межа 4096. Я припускаю, ви могли б mallocбуфер.
Кіт Томпсон,

2
Досить справедливо. Бій ножами == запобіг!
synthesizerpatel

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

2
Так. Цей метод є жахливим, але він відповідає на питання ОП.
синтезаторпател

2
Ви можете пояснити, що ви маєте на увазі під шоу жахів? Мені здається, ти намагаєшся застерегти від чогось, але я не впевнений, що ... ти просто намагаєшся вказати на небезпеку переповнення, використовуючи "% *"?
cheshirekow

117

Ви можете використовувати наступну техніку:

Це надрукує "=====" Це працює для мене на Visual Studio, немає причини, що це не повинно працювати на всіх компіляторах C.


3
Прикро, що цю відповідь не оцінюють вищою, оскільки вона не тільки правильна, але працює міжплатформно. Тестується на OSX, Linux та OpenBSD на C, а також на Perl (який обгортає C printf anywho)
synthesizerpatel

3
Дякую, я згадав, як це робив 10 років тому, але забув це, а потім знову відкрив.
rep_movsd

19
Це не зовсім гнучко. Якщо ширина більша за самий рядок, він не надрукує більше за рядок (принаймні, не в моєму простому експерименті з gcc).
Mats Petersson

1
Це працює краще, ніж відповідь синтезатора. Коли я пробував пробіл замість нуля, а ширина дорівнює нулю, все одно друкує один пробіл. Цей ні.
чорний

1
Хороший улов! @rep_movsd
Хуан Дієго Годой Роблес

24

Якщо ви обмежитеся повторенням 0 або пробілу, ви можете зробити:

Для просторів:

Для нулів:


17

У c ++ ви можете використовувати std :: string, щоб отримати повторюваний символ

Наприклад:

вихід:


17
Питання було про С, а не С ++.
Кіт Томпсон,

9
Хоча це не суто C, це мені допомогло. Дякую
автоматизуйте це


12

Немає такого. Вам доведеться або написати цикл, використовуючи, printfабо puts, або написати функцію, яка копіює рядок, що рахує рази, у новий рядок.


2
Дуже дивно, що я можу мати найскладніші вирази, але щось таке, як повторення символу, не підтримується.
Muis

Чому? Ви можете зробити це, просто додавши цикл навколо того, що ви хочете повторити. Більшість із того, що робить printf - це те, чого ви не могли зробити у власному коді [дуже легко]. Нехай бібліотеки виконують важку роботу, а прикладна програма робить прості частини, я думаю, що це тема тут.
Mats Petersson

5
І якщо ви сильно до цього ставитесь, я гадаю, що комітет зі стандартів С зацікавлений у пропозиціях щодо вдосконалення, і зразок реалізації всередині glibc, можливо, покращить шанси, що він коли-небудь стане стандартним. Якщо ви його впровадите, можливо, хтось інший подумає, що це гарна ідея. Він відсутній лише протягом останніх 50 років або близько того з моменту першого введення printf, тож, можливо, це просто недогляд ...;)
Mats Petersson

@MatsPetersson Це не рішення, оскільки я не знаю заздалегідь рядок форматування, див. Мою відповідь Мокаммелю.
Muis

3
Чому це голосування проти - якщо ви проти цього відповіді, будь ласка, дайте мені знати, з чим ви незадоволені ...
Mats Petersson

6

printfне робить цього - і printfнадмірно друкує один символ.

Не переживайте, що це неефективно; putchar()буферизує свій вихід, тому він не буде виконувати фізичну операцію виведення для кожного символу, якщо це не потрібно.


Я не знаю рядок формату або аргументи, які будуть передані в мою функцію, їх можна прочитати з xml-файлу або ввести користувачем.
Muis

У вас є символ і кількість разів, коли вам потрібно його надрукувати, так? Яка додаткова інформація вам потрібна? Для друку одного символу за printfдопомогою рядка формату має бути "%c". Але вам не потрібно використовувати printf, і в такому випадку вам зовсім не потрібен рядок форматування. (Просто не існує printfрядка формату, який би надрукував символ кілька разів, але є інші та кращі способи виконати завдання.)
Кіт Томпсон,

Як я вже сказав, я не знаю, що представляють аргументи моєї функції. Припустимо, я прочитав рядок формату та аргументи з XML-файлу і передав їх printf (), як моїй функції коли-небудь буде відомо, що їй потрібно виконати цикл і що другий аргумент представляє рахунок? Це те, що я маю на увазі, оскільки моє введення невідомо під час компіляції.
Muis

4
@ Джошуа: Аргументи якої функції? У вашому запитанні навіть не згадується функція.
Кіт Томпсон,

1
@Joshua ви дійсно розгублені, що видно з вашого надмірного використання часу компіляції та функції "збирається знати". Це насправді не так складно, як те, що ви робите, щоб воно з’явилося. Вам потрібна функція для друку символу "x" n разів. Якщо він походить від xml, тоді проаналізуйте xml і з’ясуйте символ для друку та скільки разів йому потрібно друк. Використовуйте strlen, щоб отримати довжину рядка в місцях, де ваше поле рядка xml вирішує, скільки разів потрібно друкувати символ 'x'.
SayeedHussain

6

Якщо у вас є компілятор, який підтримує функцію alloca (), то це можливе рішення (хоча й досить потворне):

В основному він виділяє 10 байтів у стеку, які заповнюються символом '\ 0', а потім перші 9 байтів заповнюються знаком 'x'.

Якщо у вас є компілятор C99, це може бути більш акуратним рішенням:


4
Я б запропонував putchar('x')замість printf("%c", 'x').
Падду

Чому? Чи менше часу на виконання?
71GA,

4

2

Ви можете створити функцію, яка виконує цю роботу і використовує її

Це виведе


2
putchar () краще підійде для циклу repeat ()
rsaxvc

Дійсно, але я намагався зробити свій код дуже базовим, щоб його було зрозуміло для будь-якого кодера початкового рівня
Лоай Хуссейн

було б краще використовувати i < count. В іншому випадку негативний вхід для підрахунку може призвести до великої кількості небажаних відбитків.
ワ イ き ん ぐ

1

n<= sizeof(buffer)[можливо також n <2 ^ 16]

Однак оптимізатор може змінити його на, puts(buffer)і тоді відсутність EoS .....

І припущення полягає в тому, що memset - це інструкція асемблера (але все одно цикл, будь то на мікросхемі).

Власне кажучи, немає жодного рішення, якщо ви отримаєте передумову "Немає циклу".


0

-2

я думаю робити щось подібне.

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