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 我可以在不指定缓冲区的情况下写入文件吗_C_File - Fatal编程技术网

C 我可以在不指定缓冲区的情况下写入文件吗

C 我可以在不指定缓冲区的情况下写入文件吗,c,file,C,File,有没有一种方法可以使用fwrite或其他文件写入函数而不将缓冲区分配给变量 鉴于我的数据是一个简单的常量,有没有比 const uint8_t a = 'A'; const uint8_t b = 'B'; if (cond) fwrite(&a, 1, 1, out_file); else fwrite(&b, 1, 1, out_file); 编辑:对于单个字符,存在fputc(在我的搜索中没有出现,因为我正在查找write)。有没有什么方法可以处理像ints

有没有一种方法可以使用
fwrite
或其他文件写入函数而不将缓冲区分配给变量

鉴于我的数据是一个简单的常量,有没有比

const uint8_t a = 'A';
const uint8_t b = 'B';

if (cond)
   fwrite(&a, 1, 1, out_file);
else
   fwrite(&b, 1, 1, out_file);
编辑:对于单个字符,存在
fputc
(在我的搜索中没有出现,因为我正在查找write)。有没有什么方法可以处理像ints这样的多字节数据

我正在寻找防止出现这种代码的方法

const uint16_t val1 = CONST_1;
const uint16_t val2 = CONST_2;
const uint16_t val3 = CONST_3;
const uint16_t val4 = CONST_4;
const uint16_t val5 = CONST_5;

if (cond1)      { fwrite(&val1, sizeof(val1), 1, out_file); }
else if (cond2) { fwrite(&val1, sizeof(val1), 1, out_file); }
// etc
而不是简单地

if (cond1)      { fputint(CONST_1, out_file); }
else if (cond2) { fputint(CONST_2, out_file); }
// etc
我可以在没有缓冲区的情况下写入文件吗(?)

考虑到我的数据是一个简单的常量,有没有比…更好的方法

考虑下面的两种情况。在这两种情况下,
a
是缓冲区

现在的编译器真是太棒了。很可能两行代码都会发出相同的代码。代码清晰明了,让编译器处理真正的微观优化问题


对于像
int
s这样的多字节数据,有什么方法可以做到这一点吗


您需要区分在运行时存在的值和仅在编译期间存在的值

编译到程序数据部分的任何值在运行时都存在于某个地址,对于通过引用传递的多字节值来说,这是标准值(对于64位以上的值来说,这是唯一实用的选择)。这也意味着只在编译时存在的值不能直接寻址,这主要是宏(如枚举)。枚举通常在运行时静态使用,这意味着它们可能永远不会离开程序段,并成为可寻址的

但是,您可以为常量重用变量,下面是使用原始posix/linux write的两个示例:

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

enum {
    FIRST = 10000,
    SECOND,
    THIRD
};

//This can (and probably will automatically) be inlined
void write_constant(uint16_t val, int fd)
{
    write(fd, &val, sizeof(val));
}

int main (void)
{
    int fd;
    uint16_t out;
    fd = open("/tmp/testfile", O_CREAT | O_WRONLY, 0640);

    //First example, reusing variable and assigning compile time constants:
    out = FIRST;  write(fd, &out, sizeof(out));
    out = SECOND; write(fd, &out, sizeof(out));
    out = THIRD;  write(fd, &out, sizeof(out));

    //Second example, wrapping the write in a function
    //This wraps the value inside an uint16_t value on either stack or register:
    write_constant(FIRST,fd);
    write_constant(SECOND,fd);
    write_constant(THIRD,fd);

    close(fd);
    return 0;
}
#包括
#包括
#包括
#包括
枚举{
第一个=10000,
第二
第三
};
//这可以(也可能会自动)内联
无效写入常量(uint16\u t val,int fd)
{
写入(fd,&val,sizeof(val));
}
内部主(空)
{
int-fd;
uint16_t out;
fd=open(“/tmp/testfile”,O|u CREAT | O|u WRONLY,0640);
//第一个示例,重用变量并分配编译时常量:
out=FIRST;写入(fd,&out,sizeof(out));
out=SECOND;写入(fd,&out,sizeof(out));
out=THIRD;写入(fd,&out,sizeof(out));
//第二个示例,将write包装到函数中
//这会将值封装在堆栈或寄存器上的uint16_t值中:
写入_常数(第一,fd);
写入_常数(秒,fd);
写入_常数(第三,fd);
关闭(fd);
返回0;
}
在没有格式化程序的情况下直接写入多个整数时,需要注意的一点是,程序的尾数保留在文件中,并且它们大部分不可读。

我们可以使用

有没有一种方法可以在不将缓冲区分配给变量的情况下使用fwrite或其他文件写入函数

当然,您可以编写一个文本字符串,例如

fwrite("\1", 1, 1, file);

在后面的示例中,字符串的第三个位置包含一个NUL字节

但是请记住,二进制格式实际上与某些体系结构有关(在某些ARM上读取x86上编写的二进制文件并不容易,例如,因为这些处理器具有不同的功能)

当然,您应该关心这个文本字符串是否应该将整数编码为几个字节。然后使用复合文字,例如,应该更容易


在实践中,您可能更喜欢技术(因为二进制格式,如体系结构无关),在某些情况下,您可能需要格式,如。。。。(因为它们更容易调试)。您可以找到库来帮助您。

fwrite()
是使用文件流(
file*
)I/O的主要机制。如果您下拉到Unix文件描述符(
int
)I/O,就如何写入数据而言,有更多的选择,但在上下文中,您最终会执行类似于
write(fd,&a,1)
(其中,
fd
是文件描述符)。因此,实际上没有太大区别。@JonathanLeffler我想我们可以说,
write
[对于单个字节]进行系统调用[这会带来很大的开销]对于写入的每个字节。通过执行
fwrite
,数据由流在内部进行缓冲,流I/O将执行更少的系统调用(即
write
调用)。因此,
fwrite
将更有效。如果我们有一个更大的缓冲区(例如
uint8_t buf[1024];
)和do(例如
write(fd,buf,sizeof(buf))
减少了开销,并且可能faster@CraigEstey:但问题要求标题中有“无缓冲区”…:D…我同意,但你反对问题标题。@CraigEstey:速度不是问题中提到的标准。单字符
write()
调用不是特别有效(但它们的效率也不是如此之低以至于无法使用-通常,在
open()
调用上没有愚蠢的选项,等等),但将
A
B
写入一个文件不太可能真正代表工作量。读取该文件不会太令人兴奋-有点像羊:咩咩咩咩咩咩咩咩咩。我想你问错了问题。你说的“没有缓冲区”是什么意思?您可以使用
fwrite(&object,sizeof object,1,out\u file);
将任何对象写入流中。在这样做之前,您不需要将对象放入缓冲区,并且通过值将其传递给某个
fput
例程不会完成任何不同的操作。如果(cond)
与是否使用缓冲区有关?您需要解决的实际问题是什么?
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>

enum {
    FIRST = 10000,
    SECOND,
    THIRD
};

//This can (and probably will automatically) be inlined
void write_constant(uint16_t val, int fd)
{
    write(fd, &val, sizeof(val));
}

int main (void)
{
    int fd;
    uint16_t out;
    fd = open("/tmp/testfile", O_CREAT | O_WRONLY, 0640);

    //First example, reusing variable and assigning compile time constants:
    out = FIRST;  write(fd, &out, sizeof(out));
    out = SECOND; write(fd, &out, sizeof(out));
    out = THIRD;  write(fd, &out, sizeof(out));

    //Second example, wrapping the write in a function
    //This wraps the value inside an uint16_t value on either stack or register:
    write_constant(FIRST,fd);
    write_constant(SECOND,fd);
    write_constant(THIRD,fd);

    close(fd);
    return 0;
}
if (cond)
   fwrite((uint8_t[]){'A'}, 1, 1, out_file);
else
   fwrite((uint8_t[]){'B'}, 1, 1, out_file);
fwrite("\1", 1, 1, file);
fwrite("\2\3\0\17", 4, 1, file);