计算并返回C中每个单词的字母数

fykwrbwg  于 2023-02-11  发布在  其他
关注(0)|答案(3)|浏览(89)

我正在学习C语言,我给自己制造了一些小的"挑战"要解决。我必须创建一个程序,读取由下划线分隔的单词组成的输入字符串,并返回每个奇数单词的最后一个字母,后跟该单词的字符数。
输入不能为空。单词之间用1个下划线隔开。第一个和最后一个字符不能为下划线(因此不能使用_this_is_a_sentencethis_is_a_sentence__this_is_a_sentence_

    • 示例:**

输入:we_had_a_lot_of_rain_in_today
输出:e2a1f2n2

    • 说明:**

我们只考虑奇数位置的单词,所以我们只需要考虑:weaofin。现在,对于这些单词中的每一个,我们获取最后一个字符,并附加该单词的字符总数:we具有2个字符,因此它变成e2a具有1个字符,因此它变成a1of具有2个字符,因此它变成f2,并且in具有2个字符,因此它变成n2
这是目前为止我的代码

#include <stdio.h>

void str_dummy_encrypt(char *sentence)
{
    int currentWord = 1;
    int totalChars = 0;
    for (int i = 0; sentence[i] != '\0'; i++)
    {
        if (sentence[i] == '_')
        {
            if (currentWord % 2 != 0)
            {
                // I know the last char of the word is on sentence[i-1]
                // and the total chars for this word is totalChars
                // but how to return it in order to be printed?
            }
            currentWord++;
            totalChars = 0;
        } else {
            totalChars++;
        }
    }
}

int main()
{
    char sentence[100];
    while (scanf("%s", sentence) != EOF)
    {
        str_dummy_encrypt(sentence);
    }
    return 0;
}

我想我走对了路,但是我不知道如何将结果返回给main函数以便打印出来。
先谢了

a0x5cqrl

a0x5cqrl1#

...如何返回结果(?)
你有两个选择:

到达目的地

呼叫者提供了充足的目的地。

void str_dummy_encrypt(size_t dsize, char *destination, const char *sentence)

分配并返回目的地

调用方应在完成后释放返回的指针。

char *str_dummy_encrypt(const char *sentence) {
  ...
  char *destination = malloc()
  ...
  return destination;
}

覆盖源

这是一个棘手的问题,因为代码需要确保目的地不超过源,但我认为你是确定的任务要求,只要字符串长度〉1。

void str_dummy_encrypt(char *sentence) {
  char *destination = sentence;
  ...
}

其他

让我们更深入地使用 pass in destination 并返回一个指示成功/错误的标志。
使用snprintf()形成 * 字母计数 *。

// Return error flag
int str_dummy_encrypt(size_t dsize, char *destination, const char *sentence) {
  ...
        if (currentWord % 2 != 0) {
          int len = snprintf(destination, dsize, "%c%d", sentence[i-1], totalChars);
          if (len < 0 || (unsigned) len >= dsize) {
            // We ran out of room
            return -1; // failure                  
          }
          // Adjust to append the next encoding.
          dsize -= len;
          destination += len;
        }
   ...
   return 0;
}

用途

char sentence[100];
char destination[sizeof sentence + 1]; // I think worse case is 1 more than source.
...
    if (str_dummy_encrypt(sizeof destination, destination, sentence)) {
      puts("Error");
    } else {
      puts(destination);
    }

代码存在其他问题:

  • 不能像"abc"一样正确处理奇数个 * 单词 *。
  • 尝试使用前导_sentence[i-1],如"_abc"
  • 输入不良:

无宽度限制,弱测试。

char sentence[100];
    // while(scanf("%s", sentence) != EOF)
    while(scanf("%99s", sentence) == 1)
  • 或许还有其他问题。

考虑像if(sentence[i+1] == '_' || sentence[i+1] == '\0')这样的测试来检测字尾,避免上面提到的两个问题(计数和其他代码也需要调整)。

4urapxun

4urapxun2#

根据任务的描述,函数应该返回一个新的字符串,该字符串是基于传递的源字符串的格式构建的。
这意味着您需要在函数中动态分配一个字符数组,结果字符串将存储在该数组中。
由于源字符串在函数中未更改,因此函数参数应具有限定符const
而且你应该写更通用的函数。
单词之间用1个下划线分隔。第一个和最后一个字符不能是下划线(因此不能使用 * this_is_a_sentence or this_is_a_sentence * or * this_is_a_sentence *
这个函数并不能使它通用。这个函数还应该能够处理像"_this_is_a_sentence_"这样的字符串。
下面是一个演示程序,说明如何实现该功能。

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

char * str_dummy_encrypt( const char *s )
{
    size_t n = 0;

    for (const char *p = s; *p; )
    {
        size_t length = 0;

        while (length == 0 && *p)
        {
            length = strcspn( p, "_" );
            if (length == 0) ++p;
        }

        if (length != 0)
        {
            p += length;
            n += 1 + snprintf( NULL, 0, "%zu", length );
        }

        length = 0;
        while (length == 0 && *p)
        {
            length = strcspn( p, "_" );
            p += length == 0 ? 1 : length;
        }
    }

    char *result = malloc( n + 1 );

    if (result != NULL)
    {
        result[n] = '\0';

        if (n != 0)
        {
            char *current = result;

            for (const char *p = s; *p; )
            {
                size_t length = 0;

                while (length == 0 && *p)
                {
                    length = strcspn( p, "_" );
                    if (length == 0) ++p;
                }

                if (length != 0)
                {
                    p += length;
                    *current++ = p[-1];
                    current += sprintf( current, "%zu", length );
                }

                length = 0;
                while (length == 0 && *p)
                {
                    length = strcspn( p, "_" );
                    p += length == 0 ? 1 : length;
                }
            }
        }
    }

    return result;
}

int main( void )
{
    const char *s = "_we__had___a_lot_of_rain_in_today___";

    char *result = str_dummy_encrypt( s );

    if (result != NULL) puts( result );

    free( result );
}

程序输出为

e2a1f2n2

如果使用您的问题中显示的字符串"we_had_a_lot_of_rain_in_today",则输出相同。
如果再添加一个将分隔符指定为的参数,则函数将更通用

char * str_dummy_encrypt( const char *s, char c );

或者,由于所示函数实现使用标准C字符串函数strcspn,因此该函数可以接受一组分隔符,如

char * str_dummy_encrypt( const char *s, const char *delimiters );
hts6caw3

hts6caw33#

实际上,你不需要将单词读入缓冲区,你可以一次只读取一个字符,并跟踪最后一个字符、单词编号及其长度:

#include <stdio.h>

int main() {
    int c, lastc = ' ', n = 1, len = 0;
    for (;;) {
        c = getchar();
        if (c == '_' || c == '\n' || c == EOF) {
            if (n & 1) {
                printf("%c%d", lastc, len);
            }
            n++;
            len = 0;
            if (c != '_')
                break;
        } else {
            lastc = c;
            len++;
        }
    }
    printf("\n");
    return 0;
}

相关问题