C语言 将每个单词的首字母大写,其余字母转换为小写

u4dcyp6a  于 2023-11-16  发布在  其他
关注(0)|答案(7)|浏览(219)

我的任务是:
将每个单词的第一个字母大写,其余字母转换为小写。
输入PrOgRaMmInG MeThOd
预期输出Programming Method
我的代码是:

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

#define SIZE 100

void xoa(char s[100], int v)
{
    int len = strlen(s);
    for (int i = v; i < len; i++)
        s[i] = s[i + 1]; 
    s[len - 1] = '\0'; 
}

void xoakt(char *s)
{
    for (int i = 0; i < strlen(s); i++)
        if (s[i] == ' ' && s[i + 1] == ' ') 
        {
            xoa(s, i);
            i--;
        }
    
    if (s[0] == ' ')
        xoa(s, 0);
    
    if (s[strlen(s) - 1] == ' ')
        xoa(s, strlen(s) - 1);
}

int main()
{
    char s[100];

    printf("Enter string: ");
    fgets(s, 100, stdin);
    xoakt(s);
    
    for (int i = 1; i < strlen(s); i++) 
    {
        s[i] = tolower(s[i]);
        if (s[i] == " ")
        {
            break;
            for (int j = strlen(s); j >= strlen(s); j--)
            {   
                if (s[j] >= " ")
                {
                    s[j] = tolower(s[j]);
                    if (s[j] == " ")
                    { 
                        break;
                    }
                }
            }
        }
    }

    printf("%s", s);
    return 0;
}

字符串
我的程序输出Programming method
但我需要它输出Programming Method
我只是个新手,我不知道该怎么做,请帮帮忙。非常感谢!

ecfdbz9o

ecfdbz9o1#

要将 string 转换为 title case,请使用state machine。这里我们需要跟踪前面字符的空格。
只需一次遍历字符串,无需调用strlen()

#include <ctype.h>

// Convert string to title case.
char *title_case(char *s) {
  // Best to use `is...()` functions with `unsigned char` values.
  unsigned char *us = (unsigned char *) s;
  bool prior_is_whitespace = true;
  while (*us) {
    if (prior_is_whitespace) {
      *us = (unsigned char) toupper(*us);
    } else {
      *us = (unsigned char) tolower(*us);
    }
    prior_is_whitespace = isspace(*us);
    us++;
  }
  return s;
}

字符串

2nc8po8w

2nc8po8w2#

你的代码中有很多问题:

  • 在函数xoa中,如果s指向空字符串,则s[len - 1] = '\0';上的行为未定义。
  • xoakt中,每次迭代时重新计算s的长度是昂贵的。如果字符串参数为空或仅包含空格,s[strlen(s) - 1]也会有未定义的行为。
  • main中,您应该测试fgets()是否失败,它在文件末尾返回NULL,并保持s不变,从而导致未定义的行为,因为s未初始化。
  • chartolower的参数和来自<ctype.h>的其他函数应该转换为(unsigned char),以避免在char是有符号类型的平台上对负char值的未定义行为。
  • s[i] == " "是没有意义的:你正在比较一个char和一个字符串(一个char *)。你应该写s[i] == ' '
  • 内部的for循环在break语句之后从不执行。
  • 如果你删除这个break语句,for (int j = strlen(s); j >= strlen(s); j--)将只运行一次,s[j]是null终止符。
  • 在这个内部循环中,由于上述原因,s[j] >= " "s[j] == " "是不正确的。

您可以使用单个循环来解决此问题,如下面的修改版本所示:

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

int main() {
    char s[100];

    printf("Enter string: ");
    if (fgets(s, sizeof s, stdin)) {
        size_t i = 0;
        size_t j = 0;

        for (;;) {
            // skip spaces
            while (isspace((unsigned char)s[i]) {
                i++;
            }
            // stop if end of string
            if (s[i] == '\0')
                break;
            // insert a space between words
            if (j > 0) {
                s[j++] = ' ';
            }
            // capitalize the first letter of the word
            s[j++] = (char)toupper((unsigned char)s[i++];
            // lower case the remaining letters
            while (s[i] != '\0' && !isspace((unsigned char)s[i])) {
                s[j++] = (char)tolower((unsigned char)s[i++];
            }
        }
        // set the null terminator (necessary if spaces were removed)
        s[j] = '\0';
        printf("%s\n", s);
    }
    return 0;
}

字符串

nhjlsmyf

nhjlsmyf3#

我改变主要功能如下。

int main()
{
    char s[100];
    printf("Enter string: ");
    fgets(s,100,stdin);
        xoakt(s);
    
    for(int i=strlen(s)-1;i>=0;i--){
      if(i==0) {s[i]= toupper(s[i]); break;}
      if(s[i-1]==' ') s[i]=toupper(s[i]);
      else s[i]=tolower(s[i]);
    }
    printf("%s",s);
    return 0;
}

字符串
我说的对吗?
我希望我的回答能对你有所帮助。
祝你好运

sf6xfgos

sf6xfgos4#

你想要的输出被称为标题大小写,这里有一种方法:
可运行代码为here

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

/*----------------------------------------------------
    title_case()
*----------------------------------------------------*/
void title_case(char *buff)
{
char *ptr = buff;
int done = 0, new_word = 1; 

    while (!done && buff)
    {
        switch(*ptr)
        {
            case '\0':      
                done = 1;  
            break;

            case ' ': 
                new_word = 1;
                ptr++;
            break;

            default:
            break;
        }
        if(new_word)
            *ptr = (char)toupper(*ptr);
        else
            *ptr = (char)tolower(*ptr);
        new_word = 0;
        ptr++;
    }
}

int main()
{
char buff[25] =  "PrOgRaMmInG MeThOd";
    
    printf("%s after title_case() is ", buff );
    title_case(buff);
    printf("%s.\n", buff );
    return 0;
}

字符串
输出量:

PrOgRaMmInG MeThOd after title_case() is Programming Method.

z9ju0rcb

z9ju0rcb5#

这个应该能用

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

void myFunction(char *my_string) {
    int string_length;
    scanf("%[^\n]", my_string);

    string_length = strlen(my_string);
    my_string[0] = toupper(my_string[0]);  // converts first char to uppercase

    for (int i = 1; i < string_length; i++) {
        // if whitespace is found
        if (my_string[i - 1] == ' ') {
            my_string[i] = toupper(my_string[i]);
        } else {
            my_string[i] = tolower(my_string[i]);
        }
    }
}

int main() {
    char my_string[100];
    printf("Enter a string: ");
    myFunction(my_string);
    printf(my_string);
    return 0;
}

字符串

6ie5vjzr

6ie5vjzr6#

把大问题分解成小问题会使问题更容易解决。
在这种情况下,我们需要能够解决一些小问题:

  • 下套管整个管柱。
  • 将字符指针向前移动超过空格。
  • #21453;进到下一个空间。
  • 使用前两个问题来收集指向字符串中每个单词的第一个字符的指针数组。(注意这不考虑标点符号。)

每一个都是一个简单的函数。

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

void downcase_string(char *str) {
    for (; *str; str++)
        *str = tolower(*str);
}

char *advance_past_space(char *str) {
    for (; *str && isspace(*str); str++);
    return str;
}

char *advance_to_space(char *str) {
    for (; *str && !isspace(*str); str++);
    return str;
}

size_t first_letters_of_words(char *str, char **ptrs) {
    size_t found = 0;

    while (*str) {
        str = advance_past_space(str);
        if (!str) break;

        ptrs[found++] = str;
        str = advance_to_space(str);
    }

    return found;
}

字符串
一旦我们有了指向每个单词的第一个字母的指针,就很容易忽略这些指针,并将它们指向的字符大写。

int main(void) {
    char str[] = "hello world foo bar";

    char *first_letters[sizeof(str)];
    size_t found = first_letters_of_words(str, first_letters);;

    downcase_string(str);

    for (size_t i = 0; i < found; ++i)
        *first_letters[i] = toupper(*first_letters[i]);

    printf("%s\n", str);
}


测试结果:

Hello World Foo Bar

jaql4c8m

jaql4c8m7#

发布的初始实现没有使用我期望它使用的两个函数,isspacetoupper
这样的功能应该可以工作。

void do_title_case_conversion(char *str)
{
    int raise = 1; /* if zero, set case to lower */

    for(char *pc=str; *pc; pc++)
    {
        if (isspace(*pc))
            raise = 1; /* between words */
        else if (raise && isalpha(*pc))
        { /* first letter of new word */
            *pc = toupper(*pc);
            raise = 0;
        }
        else if (!raise && isupper(*pc))
            *pc = tolower(*pc); /* middle of word */
    }
}

字符串

相关问题