c - 如何从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);
}
解决方案
一个有两个单独的要求:
- 打印无重音拉丁字母的特定字符的直方图
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;
}
一个人的需求很容易溢出,这会检测到它并退出。
推荐阅读
- terminal - 如何找出导致它始终显示的原因并将其删除?
- r - ggplot2 - 带有地毯图的自定义直方图
- .net - /signin-oidc 多个客户端实例上的 404(数据保护问题)
- html - 如何在没有互联网连接的情况下使用 Google 字体
- c# - 如何使用 Webdriver Selenium C# 执行每个标记表(tr)的 onclick
- php - Bug 菜单侧边栏 PHP Yii 1.1 使用模板
- javascript - 如何使用 React DnD 获取实时坐标
- c# - 在 C# 中过滤 Xml 中的属性并修改 Xml
- python - 如何在python中将文件路径作为全局变量?
- sql - 在oralce中按降序对字符串和数字组合进行排序