C 对文件内容使用atoi()时出现意外结果,请逐个字符读取
我有一个文本文件,其中只有数字(0、1、2和3),我想处理数据以了解每个数字出现的次数 下面的程序使用小文本文件(查看 我明白了 参数C 对文件内容使用atoi()时出现意外结果,请逐个字符读取,c,file,atoi,C,File,Atoi,我有一个文本文件,其中只有数字(0、1、2和3),我想处理数据以了解每个数字出现的次数 下面的程序使用小文本文件(查看 我明白了 参数 str-指向要解释的以null结尾的字节字符串的指针 但是 char c; /* ... */ nb = atoi(&c); 您正在使用一个指向单个字符的指针,该字符后面跟有谁知道是什么。 对于碰巧不是'\0'的任何内容,您将从atoi()获得一个结果,该结果是 a) 基于超出预期变量的访问 b) 对于以下数字,是两位数或更高的数字 第一个选项意味着
str-指向要解释的以null结尾的字节字符串的指针 但是
char c;
/* ... */
nb = atoi(&c);
您正在使用一个指向单个字符的指针,该字符后面跟有谁知道是什么。
对于碰巧不是'\0'
的任何内容,您将从atoi()
获得一个结果,该结果是
a) 基于超出预期变量的访问
b) 对于以下数字,是两位数或更高的数字
第一个选项意味着您的代码需要修复。
第二个选项可以解释任何大于9的数字。查看
我明白了
参数
str-指向要解释的以null结尾的字节字符串的指针
但是
char c;
/* ... */
nb = atoi(&c);
您正在使用一个指向单个字符的指针,该字符后面跟有谁知道是什么。
对于碰巧不是'\0'
的任何内容,您将从atoi()
获得一个结果,该结果是
a) 基于超出预期变量的访问
b) 对于以下数字,是两位数或更高的数字
第一个选项意味着您的代码需要修复。
第二个选项可以解释任何大于9的数字。您的问题是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....
}
}
您的问题是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....
}
}
您使用指向char
的指针调用atoi
,该指针未指向正确的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;
}
#包括
int main(){
文件*文件;
int c,i;
整数计数[10]={0};
file=fopen(“../data”,“r”);
if(file==NULL){
printf(“错误文件:%s”,strerror(errno));
返回退出失败;
}
而((c=getc(文件))!=EOF){
如果(c>='0'&&c调用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;
}
#包括
int main(){
文件*文件;
int c,i;
整数计数[10]={0};
file=fopen(“../data”,“r”);
if(file==NULL){
printf(“错误文件:%s”,strerror(errno));
返回退出失败;
}
而((c=getc(文件))!=EOF){
如果(c>='0'&&c数字(如100)或只有一位数字?有一位数字,一次只能读取0、1、2或3个字符不是很有效-您可能会发现,如果您在块中读取并处理请显示示例输入的数据,效果会更好。数字是如何分开的?永远不要使用atoi(系列)。使用strtol(系列)相反。它们是100%等效的,除了strto…具有正确的错误处理,并且支持比十进制数字更多的基数(例如100)或者只有一个数字?有一个数字,一次只能读取0、1、2或3个字符,效率不高-如果您在块中读取并处理请显示示例输入,您可能会发现效果更好。数字是如何分开的?永远不要使用atoi(族)。使用strtol(族)相反,它们是100%等效的,除了strto…有正确的错误处理,并且支持比十进制更多的基数。非常感谢,一切都是用这种转换方式工作的!这取决于一个事实,在ASCII表中,数字0
到9
在一个块中。这实际上是由C标准为所有s提供的保证支持的编码,不仅仅是ASCIIMany谢谢,一切都在以这种方式转换!这取决于一个事实,即在ASCII表中,0
到9
的数字在一个块中。实际上,C标准保证了所有支持的编码,而不仅仅是AsciiAnks!我改变了转换为Chr的方式是建议的。一切都在运转!我按照克里斯的建议改变了我的转换方式。一切都在运转