我有一个文本文件,其中只有数字(0、1、2和3),我想处理数据以知道每个数字出现多少次。
以下程序适用于较小的文本文件(<100个数字),但适用于较大的文件(我需要处理最后几千个数据),该程序读取不在文本文件中的数字。
这是我的代码:
FILE *file;
char c;
int nb;
int th0 = 0, th1 = 0, th2 = 0, th3 = 0;
file = fopen("../data", "r");
if (file == NULL) {
printf("ERROR FILE: %s", strerror(errno));
return EXIT_FAILURE;
}
while (1) {
if (fscanf(file, "%c", &c) == EOF)
break;
nb = atoi(&c);
printf("%d", nb);
switch (nb) {
case 0:
th0++;
break;
case 1:
th1++;
break;
case 2:
th2++;
break;
case 3:
th3++;
break;
default:
break;
}
}
任何建议,我将不胜感激。
编辑,输入文本和输出:
数据文件(181个数字):
001110120101010102012012021201021202102012012012012010210210210120120230103120130230123201320310231023102302301231203213210131032103210230120320310320213202301320123120312302321023
输出: The end of the reading is not what is in the data file and count 156 numbers
答案 0 :(得分:4)
您的问题是atoi
需要一个字符串,而您这样调用它:
nb = atoi(&c);
,c
只是char
。有时候这可能行得通,但是由于无法保证c
之后的内存为空,因此您基本上遇到了未定义的行为。
相反,您想以不同的方式计算nb
。
nb = c - '0';
这取决于以下事实:在ASCII表中,数字0到9在一个块中在一起。从c
中减去'0'的值将得到该字符的数值...假设它是一个数字。
为了确保它是一个数字,您应该将此if
语句包装在您的代码中
if(isdigit(c)) // Check if c is a digit
{
nb = c - '0';
switch(nb) {
case 0: th0++;
break;
// rest of switch goes here....
}
}
答案 1 :(得分:3)
看着
https://en.cppreference.com/w/c/string/byte/atoi
我知道
参数
str-指向要解释的以空终止的字节字符串的指针
但使用
PS C:\Users\atroach\Documents\GitHub\OfficeShortcuts> .\OfficeShortcuts.ps1 -c
...
Select which items you would like placed on the desktop:
1: Word
2: Excel
3: PowerPoint
4: Outlook
5: Access
6: OneNote
7: Publisher
D: Press 'D' when done.
You have selected: Excel PowerPoint
Please make a selection: d
PS C:\Users\username\Documents\GitHub\OfficeShortcuts>
您正在使用指向单个char c;
/* ... */
nb = atoi(&c);
的指针,后跟who-knows-what。
对于碰巧不是char
的任何事物,您将从'\0'
得到的结果是
a)基于超出预期变量的访问权限
b)对于以下数字,是两位数字或更高的数字
第一个选项意味着您的代码需要修复。 第二个选项可以解释任何数字> 9。
答案 2 :(得分:0)
您使用指向atoi
的指针调用char
,该指针未指向正确的C字符串,因此您的代码具有未定义的行为,有时可能会按预期工作,而在其他时候却表现不佳。
由于要处理数字,因此可以用简单的减法c - '0'
计算数字所代表的值。
您还可以使用数组简化代码:
#include <stdio.h>
int main() {
FILE *file;
int c, i;
int count[10] = { 0 };
file = fopen("../data", "r");
if (file == NULL) {
printf("ERROR FILE: %s", strerror(errno));
return EXIT_FAILURE;
}
while ((c = getc(file)) != EOF) {
if (c >= '0' && c <= '9')
count[c - '0']++;
}
fclose(file);
printf("counts:\n");
for (i = 0; i < 10; i++) {
printf("%d: %d\n", i, count[i]);
}
return 0;
}