Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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/4/c/65.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
Arrays fgets()在数组中存储什么_Arrays_C_String_Char_Fgets - Fatal编程技术网

Arrays fgets()在数组中存储什么

Arrays fgets()在数组中存储什么,arrays,c,string,char,fgets,Arrays,C,String,Char,Fgets,所以我在Kernighan和Ritchie的书中寻找fgets()。所以它是这样的: char*fgets(char*s,int-n,FILE*stream) fgets最多读取数组s中接下来的n-1个字符,如果遇到换行符,则停止;换行符包含在数组中,数组以“\0”结尾。fgets返回s,如果文件结束或出现错误,则返回NULL 所以我的困惑是,如果一个文件包含以下行 地球是太阳的第三颗行星 已知唯一有生命的天体 大约29%的地球表面是由大陆和岛屿组成的陆地 如果使用fgets()读取文件,那么

所以我在Kernighan和Ritchie的书中寻找fgets()。所以它是这样的:

char*fgets(char*s,int-n,FILE*stream)

fgets最多读取数组s中接下来的n-1个字符,如果遇到换行符,则停止;换行符包含在数组中,数组以“\0”结尾。fgets返回s,如果文件结束或出现错误,则返回NULL

所以我的困惑是,如果一个文件包含以下行

地球是太阳的第三颗行星
已知唯一有生命的天体
大约29%的地球表面是由大陆和岛屿组成的陆地
如果使用fgets()读取文件,那么“s”将包含什么?
它会包含
“地球是来自太阳的第三颗行星\n\0”
还是包含
“地球是来自太阳的第三颗行星\0\n”
或其他内容?

好的,让我们编写一些代码来查看数组中存储的内容

#include <stdio.h>

int main(void) {
    char s[64];
    int size = sizeof(s);
    int i;
    /* initialize array */
    for (i = 0; i < size; i++) s[i] = (char)0xff;

    /* call fgets() */
    fgets(s, size, stdin);

    /* print contents of the array */
    for (i = 0; i < size; i++) {
        printf("%02X ", (unsigned char)s[i]);
        if ((i + 1) % 16 == 0) {
            int j, offset = (i / 16) * 16;
            for (j = 0; j < 16; j++) {
                putchar(0x20 <= s[offset + j] && s[offset + j] < 0x7f ? s[offset + j] : '.');
            }
            putchar('\n');
        }
    }
    return 0;
}
:

45 61 72 74 68 20 69 73 20 74 68 65 20 74 68 69地球是地球
72 64 20 70 6C 61 6E 65 74 20 66 72 6F 6D 20 74第三颗行星从t
68 65 20 53 75 6E 0A 00日日日日日日日。。。。。。。。。。
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF。。。。。。。。。。。。。。。。
它包含
“地球是太阳的第三颗行星\n\0”

让我们检查一下指定的缓冲区长度小于存储该缓冲区所需大小的情况

更换
fgets(s、尺寸、标准尺寸)带有
fgets(s,32,stdin),我得到:

45 61 72 74 68 20 69 73 20 74 68 65 20 74 68 69地球是地球
72 64 20 70 6C 61 6E 65 74 20 66 72 6F 6D 20 00第二颗行星。
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF。。。。。。。。。。。。。。。。
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF。。。。。。。。。。。。。。。。

这表明在这种情况下,它将存储
n-1个
字符和1个终止空字符。

以下是C标准本身对
fgets
的描述-

§7.21.7.2

fgets函数从中读取的字符数最多比n指定的字符数少一个 由stream指向的流进入由s指向的数组。一个字符后不读取其他字符 新行字符(保留)或在文件结尾之后。立即写入空字符 在读取到数组中的最后一个字符之后

#include <stdio.h>

int main(void) {
    char s[64];
    int size = sizeof(s);
    int i;
    /* initialize array */
    for (i = 0; i < size; i++) s[i] = (char)0xff;

    /* call fgets() */
    fgets(s, size, stdin);

    /* print contents of the array */
    for (i = 0; i < size; i++) {
        printf("%02X ", (unsigned char)s[i]);
        if ((i + 1) % 16 == 0) {
            int j, offset = (i / 16) * 16;
            for (j = 0; j < 16; j++) {
                putchar(0x20 <= s[offset + j] && s[offset + j] < 0x7f ? s[offset + j] : '.');
            }
            putchar('\n');
        }
    }
    return 0;
}
回答你的问题,这里有两件主要的事情需要注意

  • fgets函数从stream指向的流到s指向的数组中读取的字符数最多比n指定的字符数少一个

    因此,您传递的
    n
    表示要读取的最大字符数,包括空终止符

    因此,如果您将
    100
    作为
    n
    传递,它将从文件中最多读取99个字符,并在该文件的末尾放置一个
    '\0'

    “最多”是什么意思?嗯,
    fgets
    将在遇到新行时停止(或者如果文件刚刚结束,显然)

    新行字符(保留)后或文件结尾后不会读取其他字符

    这意味着
    fgets
    将从文件中读取最多并包含第一个换行符
    \n
    ,或最多读取最多
    n-1
    个字符,以先发生的为准

  • 在读取到数组中的最后一个字符之后立即写入空字符

    #include <stdio.h>
    
    int main(void) {
        char s[64];
        int size = sizeof(s);
        int i;
        /* initialize array */
        for (i = 0; i < size; i++) s[i] = (char)0xff;
    
        /* call fgets() */
        fgets(s, size, stdin);
    
        /* print contents of the array */
        for (i = 0; i < size; i++) {
            printf("%02X ", (unsigned char)s[i]);
            if ((i + 1) % 16 == 0) {
                int j, offset = (i / 16) * 16;
                for (j = 0; j < 16; j++) {
                    putchar(0x20 <= s[offset + j] && s[offset + j] < 0x7f ? s[offset + j] : '.');
                }
                putchar('\n');
            }
        }
        return 0;
    }
    
    这意味着,根据前面提到的术语,从文件中读取所有字符后,
    \0
    将写入缓冲区

为了回答您的问题,在您的示例文件中,如果您使用了
fgets(s,1024,file)
-假设
s
是一个指向字符数组/缓冲区的指针,该数组/缓冲区至少可以容纳1024个字符,并且
file
是一个指向您的文件的
文件*
,您将得到结果

地球是距离太阳第三颗行星\n\0

由于
fgets
在第一次
\n
时停止,如
n
所示,在通过字符限制之前发生的情况。然后将
\0
放在缓冲区的末尾


请注意,
fgets
不仅写入传递给它的缓冲区,而且还返回相同的缓冲区-不要对此感到混淆。它们是指向同一位置的指针。

正如您所说,
char*fgets(char*str,int n,FILE*stream)
从指定的流(stdin,FILE..)读取一行,函数读取行并在到达文件结尾或读取(n-1)个字符时停止

因此,在您的示例中,
s
将包含
地球是来自太阳的第三颗行星\n\0


行中字符数大于(n-1)的另一种情况。设n=10,则
s
将包含
Earth is\0

K&R描述的哪一部分让您感到困惑?这将取决于传递给
fgets()
@MikeCAT的缓冲区长度:问题中没有提到缓冲区长度,您的陈述不准确。读取的数量也可能取决于输入中是否有换行符。假设FGET存储以下内容:
“地球是距离太阳第三颗行星\0\n”
。在
'\0'
之后存储什么重要吗?请记住,字符串由
'\0'
终止。