Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.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 POSIX读取(2),意外行为_C_Posix_Undefined Behavior - Fatal编程技术网

C POSIX读取(2),意外行为

C POSIX读取(2),意外行为,c,posix,undefined-behavior,C,Posix,Undefined Behavior,我在学习测试中使用read(2)时遇到一些问题 代码如下: #include <stdio.h> int main() { size_t length; read(0, &length, sizeof(length)); printf("input = %u\n", length); return 0; } 但是这个版本的代码就像我期望的那样: #include <stdio.h> int main() { int

我在学习测试中使用read(2)时遇到一些问题

代码如下:

#include <stdio.h>

int main() {
    size_t length;
    read(0, &length, sizeof(length));
    printf("input = %u\n", length);

    return 0;
}
但是这个版本的代码就像我期望的那样:

#include <stdio.h>

int main() {
    int a = 10;
    size_t length;
    int b = 123;
    ssize_t n = read(0, &length, sizeof(length));
    printf("input = %u\n", length);

    return 0;
}


$ ./test
input = 10
#包括
int main(){
INTA=10;
尺寸与长度;
int b=123;
ssize_t n=read(0,&length,sizeof(length));
printf(“输入=%u\n”,长度);
返回0;
}
美元/测试
输入=10
那么,重点是什么? 为什么如果我添加一些随机和未使用的变量,并且如果我存储read()的返回值,那么来自相同输入的输出将不同


注意:我知道read(2)是一个原始的系统调用,不应该从终端读取输入,这只是一个学习问题。

如果大小t为8字节,请在打印中尝试%llu

如果
大小f(大小t)==8
,代码将读取8字节-true

通常,这些字节不都是ASCII(意味着有些字节将设置第8位,并且值的范围为0x80..0xFF,这不是ASCII的一部分)

但是,没有字符转换。如果文件包含
12345678
,则该值将为0x31323334353637338(或者可能为0x3837363534333231)。如果需要转换,则不使用
read(2)

printf()
格式应该是
%zu
(C99)或
%lu
(C89的
大小等于64位
无符号长
;当然,它不能是
无符号长
和C89)

请注意,示例输出不是来自示例代码。示例输出显示
len=…
,但代码将生成
input=…
。所以,你的问题之一可能是你没有测试你认为你正在测试的东西

您的评论:

我知道read(2)是一个原始的系统调用,不应该从终端读取输入

read(2)
系统调用(可能)由
getchar()
等函数用于从终端读取。使用它从终端读取数据是正确的。从终端读取字符数组以外的内容可能是不正确的


我只需从终端运行程序,然后从键盘按enter键

哦。麻烦。我从没想过你会那样做

嗯,你把一个字节的数据读入一个需要8个字节的变量,你就会得到垃圾。您的变量未可靠初始化

下面是一个带有示例输出的SSCCE():

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    size_t length = 0xFFFFFFFFFFFFFFFF;
    int nbytes = read(0, &length, sizeof(length));
    printf("nbytes = %d: input = %zu (0x%zX)\n", nbytes, length, length);
    return 0;
}
#包括
#包括
内部主(空)
{
大小\u t长度=0xFFFFFFFFFFFFFF;
int nbytes=读取(0,&length,sizeof(length));
printf(“n字节=%d:输入=%zu(0x%zX)\n”,n字节,长度,长度);
返回0;
}
两个样本运行:

$ ./test

nbytes = 1: input = 18446744073709551370 (0xFFFFFFFFFFFFFF0A)
$ ./test
12345678
nbytes = 8: input = 4050765991979987505 (0x3837363534333231)
$ ./test < /dev/null
nbytes = 0: input = 18446744073709551615 (0xFFFFFFFFFFFFFFFF)
$
$/测试
n字节=1:输入=18446744073709551370(0xFFFFFFFFFF0A)
美元/测试
12345678
n字节=8:输入=4050765991979987505(0x3837363534333231)
$/测试
你看到那里发生了什么吗?请注意,SSCCE代码关注并报告读取的字节数。务必始终检查类读取操作的返回值(这里,这意味着
read()
);如果你没有得到你期望的那么多数据,你的结果可能也不是你期望的。在“hit newline”案例之后使用值可能是“未定义的行为”,尽管所显示的行为通常是您通常会得到的


(在Mac OS X 10.8.3上使用GCC 4.7.1进行测试-英特尔芯片,little endian。)

如何将数据送入程序?在程序中输入的是什么-输入数据是什么。(还有一个
len=4195338
应该是
input=4195338
)@JonathanLeffler我只是从终端运行程序,然后从键盘按回车键。对不起,
len=…
只是复制粘贴过程中的一个错误。我编辑。感谢您提供的其他信息。提供SSCCE()有很多好处,因为这样我们可以看到您真正在做什么。它只会在代码中添加6-10行(最多)。它还可能解答程序输入是什么的谜团-您还没有展示它。只有main()相关的LOC。顺便说一句,我会编辑这个问题^^非常感谢你。但是,为什么在第二个版本中我得到10作为输出?长度变量也未初始化。纯粹是意外,
length
变量恰好被初始化为0,因此读取换行符(
'\n'
或10)恰好将最低有效字节设置为10。我在那个字节中得到了0x0A。您也在使用一个小小的endian(英特尔)CPU。由于
length
未在代码中显式初始化,因此无法可靠地预测修改其中一个字节时将得到的值,因为其他七个字节没有确定的值。
$ ./test

nbytes = 1: input = 18446744073709551370 (0xFFFFFFFFFFFFFF0A)
$ ./test
12345678
nbytes = 8: input = 4050765991979987505 (0x3837363534333231)
$ ./test < /dev/null
nbytes = 0: input = 18446744073709551615 (0xFFFFFFFFFFFFFFFF)
$