Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 对文件内容使用atoi()时出现意外结果,请逐个字符读取_C_File_Atoi - Fatal编程技术网

C 对文件内容使用atoi()时出现意外结果,请逐个字符读取

C 对文件内容使用atoi()时出现意外结果,请逐个字符读取,c,file,atoi,C,File,Atoi,我有一个文本文件,其中只有数字(0、1、2和3),我想处理数据以了解每个数字出现的次数 下面的程序使用小文本文件(查看 我明白了 参数 str-指向要解释的以null结尾的字节字符串的指针 但是 char c; /* ... */ nb = atoi(&c); 您正在使用一个指向单个字符的指针,该字符后面跟有谁知道是什么。 对于碰巧不是'\0'的任何内容,您将从atoi()获得一个结果,该结果是 a) 基于超出预期变量的访问 b) 对于以下数字,是两位数或更高的数字 第一个选项意味着

我有一个文本文件,其中只有数字(0、1、2和3),我想处理数据以了解每个数字出现的次数

下面的程序使用小文本文件(查看

我明白了

参数
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的方式是建议的。一切都在运转!我按照克里斯的建议改变了我的转换方式。一切都在运转