【问题标题】:Return first letter of each word capitalized返回每个单词的首字母大写
【发布时间】:2016-12-23 13:08:31
【问题描述】:

我正在尝试编写一个函数来获取一个字符串,并返回每个单词的首字母大写。

例如:'天空中的太阳' => TSITS

这是我的代码。经过一番修补后,我设法能够编译;但似乎它只打印字符串的空格

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <cs50.h>   // typedef char *string; string GetString();

int main(void)
{
    string s = GetString();

    for (int i=0;i<strlen(s);i++){
        if(i == s[0] || s[i-1] == ' ' ){
            s[i] = toupper(s[i]);
            printf("%c",i);
            i++;
        }
    }
}

它有什么问题?

【问题讨论】:

  • if (i == s[0] 那应该怎么做?
  • i == s[0] 应该测试什么?
  • 什么是stringGetString()
  • 为什么要打印索引而不是字符?
  • i == s[0] 永远不会是真的,除非你真的有一个非常长的字符串或一个空字符串。当i == 0 时,s[i-1] 越界。

标签: c cs50


【解决方案1】:
  • 使用了stringGetString,但您没有定义它们,或者您没有透露定义它们的命令行或环境。
  • 条件i == s[0] 是无意义的,因为它将索引与第一个字符的字符代码进行比较。它还可能导致对s[-1] 的超出范围访问调用未定义的行为
  • 打印语句printf("%c",i); 是错误的,因为它打印的是索引而不是字符。

试试这段代码,它处理输入的第一行:

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

int main(void)
{
    char s[1024];
    char last_character = ' '; /* to deal with word lying on multiple chunks */

    /* repeat for the case where the line to deal with is too long to fit in one chunk */
    while (fgets(s, sizeof(s), stdin) != NULL) {
        int i;
        /* calling strlen() in every loop is not effective */
        for (i = 0; s[i] != '\0'; i++){
            /* check if currently looking at the first charater of each words */
            if(isalpha((unsigned char)s[i]) && (i == 0 ? last_character : s[i-1]) == ' '){
                /* cast to unsigned char to avoid undefined behavior invoked by passing out-of-range value */
                printf("%c", toupper((unsigned char)s[i]));
                /* incrementing i here may cause skipping the terminating null-character for the new loop condition, so remove it */
            }
        }
        if (i > 0) {
            /* save the last character in this chunk */
            last_character = s[i - 1];
            /* deal with only the first line */
            if (last_character == '\n') break;
        }
    }
    putchar('\n');
    return 0;
}

【讨论】:

  • 感谢您的快速回答,我需要一些时间和大量的谷歌搜索才能完全理解发生了什么:)
  • 谷歌搜索提示:三元运算符用于(i == 0 ? last_character : s[i-1])
  • 感谢您的提示,实际上三元运算符可能是我得到的东西之一,我来自 Ruby :)
【解决方案2】:
string func(string s){
//take a string, and return the first letter of each word capitalized.
    char pre = ' ', curr;
    int new_i = 0;

    for(int org_i = 0; curr = s[org_i]; ++org_i){
        if(isspace(curr))
            pre = ' ';
        else if(pre == ' ')
            s[new_i++] = toupper(pre = curr);
    }
    s[new_i] = 0;
    return s;
}

int main(void){
    string s = GetString();

    puts(func(s));
    free(s);

    return 0;
}

【讨论】:

    【解决方案3】:

    而不是使用i == s[0](可能是i == 0),只需跟踪前一个字符。

    char previous = ' ';
    
    // Don't recalculate the length each time, just look for the null character
    // for (int i=0;i<strlen(s);i++){
    for (; *s; s++){
        if(previous == ' ' && isalpha((unsigned char) *s)) {
          printf("%c",toupper((unsigned char) *s));
          // or 
          putchar(toupper((unsigned char) *s));
        }
        previous = *s; 
    }
    

    【讨论】:

      【解决方案4】:

      坦率地说很容易。

      //First the includes
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <ctype.h>
      #include <cs50.h>
      
      int main(void) {
              string str = GetString(); //Here you should enter your string
              str[0] = toupper(str[0]); //Capitalize the first letter so you don't have to do extra checking in the for loop
              for (int i = 1; i < strlen(str); i++){ //Start from the second letter(or space) since index 0 is already capitalized
                      if(str[i-1] == ' ') //Check if the previous character was a space
                              str[i] = toupper(str[i]); //Convert to uppercase
              }
              puts(str); //Print out the string, same thing as printf(str);
      }
      

      希望能帮到你:)

      【讨论】:

        猜你喜欢
        • 2020-08-30
        • 2016-12-05
        • 2015-11-10
        • 2015-11-04
        • 2017-08-02
        • 2012-11-11
        • 1970-01-01
        • 2013-12-15
        • 2012-07-24
        相关资源
        最近更新 更多