首页 > 解决方案 > 如何从C中的文本文件中计算数字

问题描述

所以我的程序应该从文件中获取输入,读取每个字符并将字符的频率放入输出文件中。如果字符是数字,它应该给出文本中所有数字(而不是数字)的总和。例如,来自文件的输入是“aae 40 20”,它应该给出数字的总和,即 60 等等。到目前为止,我已经完成了每个角色的频率。似乎我无法弄清楚如何将所有数字的总和作为输出。这是我的代码:

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

char input_datei[20];
 char alphabet[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r',
    's','t','u','v','w','x','y','z'};
    //Intiaialsie a frequency array, to count the frequency of every alphabet
int frequency[26]={0};
void textAnalysieren(FILE *input,FILE *output,char character,int counter);
int main()
{
    //Requiring a File's name with Length max 20 char long.
    puts("Please give a name for the file to analyse!");
    scanf("%20s",input_datei);

    int counter=0;
    char character;
    FILE *in= fopen(input_datei,"r");
    //If file doesn't exist
    if(in==0){
        printf("Error opening the file\nFile might not exist!\n");
        return 1;
    }
    FILE *out=fopen("ausgabe.txt","w");

    textAnalysieren(in,out,character,counter);

    //close the files
    fclose(in);
    fclose(out);
    return EXIT_SUCCESS;
}
void textAnalysieren(FILE *input,FILE *output,char character,int counter){
     // Loop through every character in the FIle feof return true, when EOF is found
    while((character=fgetc(input)) != EOF){
        // Differentiate between numbers and character's!
        if((character >= 48) && (character <=57)){

                counter =counter+ (character -48);
                if(((character+1) >= 48) && ((character+1) <=57)){
                    counter *=10;
                    counter = counter+((character+1)-48);
                }
               }
        else{
                character= tolower(character);
                for(int s=0;s<26;s++){
                    if(alphabet[s]==character){
                        frequency[s]++;
                    }
                }
    }
}
     //Write to the ausgabe.txt File the Frequency of each character of the alphabet
    for(int s=0;s<26;s++){
        fprintf(output,"Character %c came %d in the text \n",alphabet[s],frequency[s]);
    }
    fprintf(output,"The summ of all your numbers is:  %d \n",counter);
}


标签: c

解决方案


一个有两个单独的要求:

  • 打印无重音拉丁字母的特定字符的直方图a,(我假设并且A在同一个 bin 中。)
  • 设置一个丢弃非数字输入的过滤器,并对以 10 为底的连续字节数求和。

这通过直方图中没有数字来简化,这允许我们单独和同时处理问题(一次通过。)例如,这使用re2c来简化词法分析,('x'匹配不区分大小写。)

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <assert.h>

struct Scanner {
    size_t line;
    char *from, *cursor;
    long hist[26];
    long sum;
};

/*!re2c
re2c:yyfill:enable   = 0;
re2c:define:YYCTYPE  = char;
re2c:define:YYCURSOR = s->cursor;
newline = "\n" | ("\r" "\n"?);
dec = [1-9][0-9]*;
end = "\x00";
*/

/** Returns success or failure, on which case `errno` will be set. */
static int lex(struct Scanner *s) {
    assert(s);
scan:
    s->from = s->cursor;
/*!re2c
    * { goto scan; }
    end { return 1; }
    newline { s->line++; goto scan; }
    'a' { s->hist[0]++;  goto scan; }
    'b' { s->hist[1]++;  goto scan; }
    'c' { s->hist[2]++;  goto scan; }
    'd' { s->hist[3]++;  goto scan; }
    'e' { s->hist[4]++;  goto scan; }
    'f' { s->hist[5]++;  goto scan; }
    'g' { s->hist[6]++;  goto scan; }
    'h' { s->hist[7]++;  goto scan; }
    'i' { s->hist[8]++;  goto scan; }
    'j' { s->hist[9]++;  goto scan; }
    'k' { s->hist[10]++; goto scan; }
    'l' { s->hist[11]++; goto scan; }
    'm' { s->hist[12]++; goto scan; }
    'n' { s->hist[13]++; goto scan; }
    'o' { s->hist[14]++; goto scan; }
    'p' { s->hist[15]++; goto scan; }
    'q' { s->hist[16]++; goto scan; }
    'r' { s->hist[17]++; goto scan; }
    's' { s->hist[18]++; goto scan; }
    't' { s->hist[19]++; goto scan; }
    'u' { s->hist[20]++; goto scan; }
    'v' { s->hist[21]++; goto scan; }
    'w' { s->hist[22]++; goto scan; }
    'x' { s->hist[23]++; goto scan; }
    'y' { s->hist[24]++; goto scan; }
    'z' { s->hist[25]++; goto scan; }
    dec {
        long no;
        char *end;
        no = strtol(s->from, &end, 10);
        if(end == s->from || (no == LONG_MAX && errno)) return 0;
        if((s->sum > INT_MAX - no)) return errno = ERANGE, 0;
        s->sum += no;
        goto scan;
    }
*/
}

int main(void) {
    char buffer[256];
    struct Scanner s;
    int success = EXIT_FAILURE;
    size_t i;
    memset(&s, 0, sizeof s); /* `hist` and `sum`. */
    s.line = 1;
    while((s.cursor = fgets(buffer, sizeof buffer, stdin))) {
        size_t len = strlen(s.cursor);
        assert(len > 0);
        if(s.cursor[len - 1] != '\n') {
            fprintf(stderr, "Line too long or embedded zeros.\n");
            errno = ERANGE;
            goto catch;
        }
        if(!lex(&s)) goto catch;
    }
    if(ferror(stdin)) goto catch;
    for(i = 0; i < sizeof s.hist / sizeof *s.hist; i++)
        if(s.hist[i]) printf("%c: %lu\n", 'a' + i, s.hist[i]);
    printf("sum: %lu\n", s.sum);
    success = EXIT_SUCCESS;
    goto finally;
catch:
    assert(!s.from || (s.from < s.cursor && s.from + INT_MAX >= s.cursor));
    fprintf(stderr, "While on line %lu: %.*s.\n", (unsigned long)s.line,
        (int)(s.cursor - s.from), s.from);
    perror("parsing");
finally:
    return success;
}

一个人的需求很容易溢出,这会检测到它并退出。


推荐阅读