簡體   English   中英

如何將除某些單詞(“和”,“但是”,“ of”)之外的每個單詞的首字母大寫?

[英]How to capitalize first letter of each word except certain words (“and”, “but”, “of”)?

給出的輸入是: the lord of the rings
預期的輸出是: The Lord of the Rings
但是我得到的是: The Lord ofof thethe Rings

碼:

#include <cs50.h>
#include <string.h>
#include <stdio.h>

int main(void)
{
  string s = GetString();
  //to print an upper case char 
  printf("%c", toupper(s[0]));


  for (int i = 1, n = strlen(s); i <n; i++)
  {
    //not to capitalize and but of
    if (isspace(s[i]))
    {
        if (s[i + 1] == 't' && s[i + 2] == 'h' && s[i + 3] == 'e') {
            printf("%c%c%c%c", s[i], s[i + 1], s[i+2], s[i+3]);
        } else if (s[i + 1] == 'a' && s[i + 2] == 'n' && s[i + 3] == 'd') {
            printf("%c%c%c%c", s[i], s[i + 1], s[i+2], s[i+3]);
        } else if (s[i + 1] == 'b' && s[i + 2] == 'u' && s[i + 3] == 't') {
            printf("%c%c%c%c", s[i], s[i + 1], s[i+2], s[i+3]);
        } else if (s[i + 1] == 'o' && s[i + 2] == 'f') {
            printf("%c%c%c", s[i], s[i + 1], s[i+2]);
        } else { //capitalize rest of the code:
            printf("%c%c", s[i], toupper(s[i + 1]));
            i++;
        }            
    } else {
        if(   (s[i] == 't' && s[i + 1] == 'h' && s[i + 2] == 'e') 
           || (s[i] == 'a' && s[i + 1] == 'n' && s[i + 2] == 'd') 
           || (s[i] == 'b' && s[i + 1] == 'u' && s[i + 2] == 't') 
           || (s[i] == 'o' && s[i + 1] == 'f' ) )
            continue;          
        else
            printf("%c",s[i]);           
     }
   }
}

請幫我解決。

在每個if子句中,跳過一個停用詞后,您需要根據該詞的長度來調整索引,例如:

if (s[i + 1] == 't' && s[i + 2] == 'h' && s[i + 3] == 'e') {
   printf("%c%c%c%c", s[i], s[i + 1], s[i+2], s[i+3]);
   i += 3; // Skip the next 3 positions
} 

這仍然不能解決不大寫“看起來像”停用詞的較長詞(例如androidbutteroffset )的問題。

我會考慮學習strtok()函數。 您可以使用它來將行分成單個單詞。 然后,如果您有一個包含不應大寫的單詞的數組,則可以使用strcmp()在此列表中檢查每個單詞,並在適當的情況下將其大寫,然后再將其添加到包含大寫字母的行中。 下面的代碼執行此操作,並且始終將第一個單詞大寫。 請注意, skip_list[]在最后一個單詞之后包含一個NULL指針; 用於遍歷列表。 還要注意,用於存儲大寫結果的數組title[]已分配,因此其長度足以容納input字符串(包括NUL終止符)。 此外, title首先被定義為一個空字符串,以便可以使用strcat()將第一個word標記與其安全地連接。

可以通過編寫upcase()函數(將單詞的第一個字母字符大寫,然后將其余字符downcase()downcase()函數(將單詞中的所有字符downcase()來改進此方法。 而不是盲目地僅改寫第一個字符,這將可以更好地處理混亂的輸入,例如"tHe lorD oF The rINgs"

最后一點:函數strtok()將通過向其中寫入'\\0'字符來修改input

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>

#define MAX_SKIP  100

bool in_list(const char *word, const char **list);

int main(void)
{
    const char *skip_words[MAX_SKIP] = { "and", "but", "of", "the", NULL };
    char input[] = "the lord of the rings";
    size_t title_sz = strlen(input) + 1;
    char title[title_sz];
    char *word;

    title[0] = '\0';
    word = strtok(input, " ");
    word[0] = toupper(word[0]);
    strcat(title, word);
    while ((word = strtok(NULL, " "))) {
        if (!in_list(word, skip_words)) {
            word[0] = toupper(word[0]);
        }
        strcat(title, " ");
        strcat(title, word);
    }

    puts(title);

    return 0;
}

bool in_list(const char *word, const char **list)
{
    while (*list != NULL) {
        if (strcmp(word, *list) == 0) {
            break;
        }
        ++list;
    }

    return *list != NULL;
}

程序輸出為:

指環王

我基於Apache的WordUtils.capitalize()方法編寫了代碼。 您可以將分隔符設置為正則表達式字符串。 如果要跳過[[and],“ but”,“ of”]之類的詞,只需將其設置為定界符即可。

public static String capitalize(String str, final String delimitersRegex) {
    if (str == null || str.length() == 0) {
        return "";
    }

    final Pattern delimPattern;
    if (delimitersRegex == null || delimitersRegex.length() == 0){
        delimPattern = Pattern.compile("\\W");
    }else {
        delimPattern = Pattern.compile(delimitersRegex);
    }

    final Matcher delimMatcher = delimPattern.matcher(str);
    boolean delimiterFound = delimMatcher.find();

    int delimeterStart = -1;
    if (delimiterFound){
        delimeterStart = delimMatcher.start();
    }

    final int strLen = str.length();
    final StringBuilder buffer = new StringBuilder(strLen);

    boolean capitalizeNext = true;
    for (int i = 0; i < strLen; i++) {
        if (delimiterFound && i == delimeterStart) {
            final int endIndex = delimMatcher.end();

            buffer.append( str.substring(i, endIndex) );
            i = endIndex;

            if( (delimiterFound = delimMatcher.find()) ){
                delimeterStart = delimMatcher.start();
            }

            capitalizeNext = true;
        } else {
            final char ch = str.charAt(i);

            if (capitalizeNext) {
                buffer.append(Character.toTitleCase(ch));
                capitalizeNext = false;
            } else {
                buffer.append(ch);
            }
        }
    }
    return buffer.toString();
}

希望對您有所幫助:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM