如何逐个单词地计算文件中的元音数量并将结果附加到单词上? [英] How to count number of vowels from file word by word and attach the results to the words?

查看:71
本文介绍了如何逐个单词地计算文件中的元音数量并将结果附加到单词上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用C语言编写一个代码,该代码从文件中读取 n 个单词并逐个单词地修改内容.

I am trying to write a code in C that reads n words from a file and modifies the content word by word.

程序将计算每个单词中的元音数量.如果当前单词中的元音数量为偶数,则程序将以两个为对交换元音(在奇数的情况下不进行交换),然后将元音数量附加到单词上.

The program will count the number of vowels in each word. If the number of vowels in the current word is even, the program will swap the vowels in pair of two (no swapping in case of odd number), then it will attach the number of vowels to the word.

例如,如果单词是 apple ,则修改后的单词将看起来像 eppla_2vow .

For example if the word is apple , the modified word will look like eppla_2vow .

我的问题是我不太了解如何逐字进行修改.

My problem is that I don't quite know how am I supposed to make the modifications word by word.

     FILE *f = fopen("input.dat","r");
     int i;
     int bufflen=256;
     char buff[bufflen];

     while(n)
     {
      fscanf(f,"%s",buff);
      n--;
     }

     int vowels=0;

     for(i=0; buff[i]!='\0'; i++)
     {
          if (buff[i] == 'a' || buff[i] == 'e' || buff[i] == 'i' ||
          buff[i] == 'o' || buff[i] == 'u' || buff[i] == 'A' ||
          buff[i] == 'E' || buff[i] == 'I' || buff[i] == 'O' ||
          buff[i] == 'U')
          { vowel++;}

          if (buff[i] == ' ')
          {
           vowels=0;
          }
     }

我什至不确定是否要以正确的方式遍历字符串以进行那些修改.

I'm not even sure if I iterate over the string the right way in order to be able to make those modifications.

我再举一个例子,假设文件的内容是:

I will give another example, let's say the content of the file is:

apple juice strawberry can make pineapple

修改后的单词将如下所示:

And the modified words will look like:

eppla_2vow juice_3vow strewbarry_2vow can_1vow meka_2vow penieppla_4vow

推荐答案

这可以分为几个子任务:

This can be broken into a few sub-tasks:

首先,我们需要一个函数来计算字符串中元音的数量.那很简单.我们可以泛化它来计算另一个字符串中某个字符串中任何字符的出现次数,而不会造成任何麻烦.

First, we need a function to count the number of vowels in a string. That's pretty straightforward. We could generalize it to count the number of occurrences of any chars in a string in another string without any trouble.

第二,我们需要一个在字符串中交换元音的函数.两指针技术似乎是解决此问题的方法.当前后指针没有碰到时,向前迭代前指针,直到它落在元音上.此时,递减后指针,直到碰到一个元音并交换它们.像这样继续交换,直到指针交叉.如上所述,很容易传递字符列表以交换为字符串.

Second, we need a function that swaps the vowels in a string. The two-pointer technique seems like the way to go for this. While the front and back pointers haven't met, iterate the front pointer forward until it lands on a vowel. At this point, decrement the back pointer until it hits a vowel and swap them. Keep swapping like that until the pointers cross. As above, it's easy to pass the character list to swap into the string.

除此之外,其他所有内容都是样板文件-将字符串放在空格和IO上.将结果写回文件而不是字符串,可以更轻松地满足 _Nvow 要求的重新分配;您可以使用 fprintf 将单词粘在一起并计数在一起.

Other than that, everything else is boilerplate--chunking the string on spaces and IO. Writing results back to a file instead of a string makes it easier to deal with reallocation for the _Nvow requirement; you can use fprintf to glue the word and count together.

将它们放在一起:

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

int str_count_in_chars(char *start, char *end, char *chars) {
    int count = 0;

    for (; start != end; count += !!strchr(chars, *(start++)));

    return count;
}

void str_swap_in_chars(size_t str_len, char **str, char *chars) {
    for (int front = 0, back = str_len - 1; front < back; front++) {
        if (strchr(chars, (*str)[front])) {
            for (; !strchr(chars, (*str)[back]); back--);

            char tmp = (*str)[front];
            (*str)[front] = (*str)[back];
            (*str)[back--] = tmp;
        }
    }
}

char *file_to_str(FILE *fin) {
    int buf_len = 64;
    char buf[buf_len];
    char *str = malloc(buf_len);
    str[0] = '\0';

    for (int i = 1; fgets(buf, buf_len, fin); i++) {
        if (!(str = realloc(str, i * buf_len))) {
            fprintf(stderr, "%s:%d realloc failed\n", __FILE__, __LINE__);
            exit(1);
        }

        strcat(str, buf);
    }

    return str;
}

int main() {
    char *vowels = "aeiou";
    FILE *fin = fopen("input.dat", "r");
    FILE *fout = fopen("output.dat", "w");

    if (!fin || !fout) {
        fprintf(stderr, "%s:%d fopen failed\n", __FILE__, __LINE__);
        exit(1);
    }

    char *words = file_to_str(fin);
    fclose(fin);
    int words_len = strlen(words);

    for (int i = 0; i < words_len;) {
        if (isspace(words[i])) {
            fputc(words[i++], fout);
            continue;
        }

        int start = i;

        for (; i < words_len && !isspace(words[i]); i++);

        char *word = words + start;
        int word_len = i - start;
        int vowel_count = str_count_in_chars(word, words + i, vowels);

        if (vowel_count % 2 == 0) {
            str_swap_in_chars(word_len, &word, vowels);
        }

        fprintf(fout, "%.*s_%dvow", word_len, word, vowel_count);
    }

    fclose(fout); 
    free(words);
    return 0;
}

执行此操作后, output.dat 包含:

eppla_2vow juice_3vow strewbarry_2vow can_1vow meka_2vow penieppla_4vow

这篇关于如何逐个单词地计算文件中的元音数量并将结果附加到单词上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆