如果行寬可以接受,我需要逐字切割字串并將它們放在行中。如果沒有,它們應該放在下一行。
輸出:
--------------------
The applicant must
have some hardware
construction
experience and be
fluent in C and
assembly language
programming.
代碼:
#include <stdio.h>
void cut_words(const char *sentence, int width) {
int i, j = 0,k, count = 0,rows=0,stop=0,rest;
for (i = 0; i < width; i )
printf("-");
printf("\n ");
while (sentence[j] != '\0') {
count ;
printf("%c", sentence[j]);
j ;
if (count> width) {
printf("\n ");
count = 0;
}
}
}
int main() {
const char sentence[1000] = "The applicant must have some hardware construction experience and be fluent in C and assembly language programming.";
int width = 20;
cut_words(sentence, width);
return 0;
}
- 注意:不能使用輔助字串。
uj5u.com熱心網友回復:
我猜你應該在不使用庫函式的情況下這樣做。行填充和中斷文本是一個經典的練習。我不知道您是否希望一次得到一個單詞來填充行,這樣輸入中的多個空格就會被折疊。如果沒有,另一種方法是從非空格開始,查看寬度將填充的位置,然后在空格或單詞中間進行備份。列印你所擁有的,然后從下一個單詞重新開始。
void cut_words(const char *sentence, int width) {
char *s = (char *)sentence;
for (int i = 0; i < width; i )
printf("-");
printf("\n");
// skip leading spaces
while (*s && *s == ' ')
s ;
while (strlen(s) > width) {
// *s must be nonspace and not EOS
char *e = s width - 1;
// *e is last char that can possibly fit
// *e cannot be EOS nor can e[1]
// back up to nonspace if at space
while (*e == ' ')
e--;
// *e is inside or end of word
if (e[1] != ' ') {
// not end of word; must be inside
// back up to prev space
while (e > s && *e != ' ')
e--;
// if e == s then no word break
// must assume word is longer than width
if (e == s)
e = s width - 1;
else
// find end of prev word
while (e > s && *e == ' ')
e--;
}
// *e is end of word
int k = e - s 1;
printf("%*.*s\n", k, k, s);
s = k;
while (*s && *s == ' ')
s ;
}
if (*s)
printf("%s\n", s);
}
現在,看看你是否可以只使用索引而不是指標來做到這一點。或者,更具挑戰性的是,嘗試沿著字串前進,找到每個單詞的開頭和結尾并列印出來,跟蹤每行還剩下多少空間。
uj5u.com熱心網友回復:
我不太喜歡我之前的回答。我認為你應該一次抓住一個單詞并用一個前導空格列印它。所以我會描述這些片段,然后讓你把它們放在一起。如果你做不到,那就展示你所擁有的,我們會從那里開始。
如上所述初始化一個指標(但我不需要丟棄 const):
const char *s = sentence;并設定一個 var 來保存要在行上填充的字符數:int nleft = width;。
跳過前導空格:while (*s && *s == ' ') s ;
現在回圈直到字串結束:while (*s)。每次進入回圈,*s將是下一個要列印的非空格字符。找到單詞之后的邊界并計算長度。如果行上沒有足夠的空間(包括空格),請列印換行符 reset nleft。然后列印一個空格和單詞,按列印的字符數(包括空格)遞減nleft。唯一的問題是如果單詞太長而無法排成一行,那么您需要分段列印。
列印后,在空格上前進s,使其位于非空格或字串末尾。在回圈之后,檢查當前行是否有任何內容,如果有則列印一個換行符。
在回圈頂部:
const char *e = s;
while (*e && *e != ' ')
e ;
int len = e - s;
如果len超過width - 1,則將其設定width - 1為您可以在一行上列印的最長部分。
如果 ,則該行為空nleft == width。如果 . 則空間不足len 1 > nleft。如果空間不足且該行非空,請列印換行符并重置nleft。然后列印從 .len開始的空格和字符s。請注意我之前的回答中使用的%*.*s格式。
列印后,s按列印的字符數遞增len和遞減nleft。現在回圈以將 s 推進到下一個非空格或字串末尾。請注意,如果您列印了一個太長的單詞的一部分(超過width-1字符),那么s已經在下一個要列印的非空格處。
另請注意,s回圈頂部的條件“指向下一個要列印的非空格”是“不變數”,這是推理回圈的重要概念。如果回圈不明顯,請考慮它應該維護哪些不變數以及退出后應該保持哪些條件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/435687.html
