Як повторити символ за допомогою 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.