我正在處理一項需要輸入的作業:
The Dhillon Theatre is now Fun Republic
和輸出:
Dhillon atre is now Fun Republic.
我的代碼以某種方式作業,但實際上洗掉了“t、h 和 e”的每個出現。而不是“the”作為一個整體。
我該怎么辦?我怎樣才能讓程式將“the”讀作一個詞而不是單獨的字符?
源代碼:
#include <stdio.h>
#include <string.h>
//The Dhillon Theatre is now Fun Republic
#define SIZE 100
int func();
int main()
{
func();
}
int func()
{
int i, j, inputlen, removelen;
char input[SIZE];
char toRemove[4] = "the";
printf("Enter the string: \n");
gets(input);
inputlen = strlen(input);
removelen = strlen(toRemove);
for (i = 0; i<inputlen; i )
{
for (j = 0; j<removelen; j )
{
if (input[i] == toRemove[j])
{
for (j = i; j<inputlen; j )
{
input[j] = input[j 1];
}
inputlen--;
i--;
}
}
}
printf("%s", input);
}
uj5u.com熱心網友回復:
我怎樣才能讓程式將“the”讀作一個詞而不是單獨的字符?
代碼失敗,因為即使標題是洗掉 "The" 和 "the" 的出現,目標是洗掉基于完整單詞的"The/the" 。
什么是詞?查看非字母的開頭和結尾。
"The", "The dog", "What the", "Where is the beef"
但不是
"", "There", "These dogs", "What lathe", "Where is other beef"
// inputlen = strlen(input);
removelen = strlen(toRemove);
const char *read = input;
const char *write = input;
char previous_non_letter = true;
while (*read) {
// was the previous char a non-letter?
if (!isalpha(previous_non_letter)) {
// match toRemove?
int i;
for (i = 0; i<removelen; i ) {
if (tolower(read[i]) != tolower(toRemove[i])) {
break;
}
}
// Complete match and next is a non-character?
if (i == removelen && !isalpha(read[i]) {
// Advance reading by removelen
read = removelen;
previous_non_letter = false;
continue;
}
}
previous_non_letter = !isalpha(read);
*write = *read ;
}
*write = '\0';
以上將"the"洗掉(如標題所述),但不會洗掉前導或尾隨的非字母(例如' ')。如果需要,將添加內容留給 OP。
假設:removelen > 0最后一個字符toRemeve是一個字母。確定洗掉“theE”。
當非字母,非空間涉及“the123 123the456 123the”時,OP的目標不清楚。
uj5u.com熱心網友回復:
一個有用的功能是能夠將字串小寫。我們暫時先把它擱置一旁。
void downcase(char *str) {
for (char *ch = str; *ch; ch ) {
if (*ch >= 'A' && *ch <= 'Z') {
*ch = *ch 32;
}
}
}
另一個有用的功能。我們要判斷一個子串是否是一個詞,所以我們需要測驗它前后的字符。顯然,就它尋找的字符而言,這可能會更復雜,但出于教育目的,這樣做是可行的。
int is_word(char *src, size_t s, size_t len) {
return ((s == 0 || src[s - 1] == ' ' || src[s - 1] == '.' || src[s - 1] == ',') &&
(s len >= strlen(src) || src[s len] == ' ' || src[s len] == '.' || src[s len] == ',' || src[s len] == '\0'));
}
現在,讓我們啟動一個remove_word函式。它將遍歷輸入字串,查看我們要替換的單詞長度的子字串。is_word如果所討論的單詞是單詞,它將使用該函式列印注釋。
當然,這只是該問題的一種解決方案。
void remove_word(char *input, char *to_remove, char* dest) {
int index;
size_t input_len = strlen(input);
size_t to_remove_len = strlen(to_remove);
char temp[to_remove_len 1];
char temp_ci[to_remove_len 1];
downcase(to_remove);
for (index = 0; index < input_len - to_remove_len 1; index ) {
strncpy(temp, input index, to_remove_len);
strncpy(temp_ci, input index, to_remove_len);
temp[to_remove_len] = '\0';
temp_ci[to_remove_len] = '\0';
downcase(temp_ci);
printf("%s", temp);
if (is_word(input, index, to_remove_len)) {
printf(" -> Word\n");
}
else {
printf("\n");
}
}
}
現在,如果我們在您的測驗字串上進行測驗:
int main() {
char *replace = "the";
char dest[100];
remove_word("The Dhillon Theatre is now Fun Republic", replace, dest);
}
我們得到這個輸出:
The -> Word
he
e D
Dh
Dhi
hil
ill
llo
lon
on
n T
Th
The
hea
eat
atr
tre
re
e i
is
is
s n
no
now -> Word
ow
w F
Fu
Fun -> Word
un
n R
Re
Rep
epu
pub
ubl
bli
lic
這對于實作您的目標非常重要。我們現在可以識別長度合適的單詞作為我們正在尋找的單詞。
The word to remove has been downcased, and we have a downcased version of the current substring. It's pretty straightforward to find out if the current word should be removed.
void remove_word(char *input, char *to_remove, char* dest) {
int index;
size_t input_len = strlen(input);
size_t to_remove_len = strlen(to_remove);
char temp[to_remove_len 1];
char temp_ci[to_remove_len 1];
downcase(to_remove);
for (index = 0; index < input_len - to_remove_len 1; index ) {
strncpy(temp, input index, to_remove_len);
strncpy(temp_ci, input index, to_remove_len);
temp[to_remove_len] = '\0';
temp_ci[to_remove_len] = '\0';
downcase(temp_ci);
if (is_word(input, index, to_remove_len)) {
printf("=: %s", index, temp);
if (strcmp(to_remove, temp_ci) == 0) {
printf(" -> Bingo!\n");
}
else {
printf(" -> Word\n");
}
}
}
}
Now when we run it:
0: The -> Bingo!
23: now -> Word
27: Fun -> Word
We now know how to find instances of the word to remove, and the index where they start.
Now we simply have to implement the copying (or not copying) into dest based on this information. For this I've added a write_index that will keep track of where to insert characters into dest.
void remove_word(char *input, char *to_remove, char* dest) {
int index, write_index;
size_t input_len = strlen(input);
size_t to_remove_len = strlen(to_remove);
char temp[to_remove_len 1];
char temp_ci[to_remove_len 1];
downcase(to_remove);
for (index = 0, write_index = -1; index < input_len - to_remove_len 1; index , write_index ) {
strncpy(temp, input index, to_remove_len);
strncpy(temp_ci, input index, to_remove_len);
temp[to_remove_len] = '\0';
temp_ci[to_remove_len] = '\0';
downcase(temp_ci);
if (is_word(input, index, to_remove_len) && strcmp(to_remove, temp_ci) == 0) {
index = to_remove_len - 1;
}
else if (index to_remove_len == input_len) {
for (int i = 0; i < to_remove_len; i ) {
*(dest write_index ) = input[index ];
}
}
else {
*(dest write_index) = input[index];
}
}
*(dest write_index) = '\0';
}
Now running your test:
int main() {
char *replace = "the";
char dest[100] = {0};
remove_word("The Dhillon Theatre is now Fun Republic", replace, dest);
printf("%s\n", dest);
}
We get:
$ ./a.out
Dhillon Theatre is now Fun Republic
$
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/335630.html
標籤:C
