当文件指针 arg 是 stdout 时,是否可以使用 fseek?
我尝试过在一个场景中使用它,当我试图用 ")" 覆盖逗号分隔列表中的最后一个 "," 时。
例如:
fprintf(stdout, "1,2,3,4,");
fseek(stdout, -1, SEEK_CUR);
fprintf(stdout, ")");
要实现:
1、2、3、4)
而非
1、2、3、4,)
不幸的是,我输出了后者。
当文件指针 arg 是 stdout 时,是否可以使用 fseek?
我尝试过在一个场景中使用它,当我试图用 ")" 覆盖逗号分隔列表中的最后一个 "," 时。
例如:
fprintf(stdout, "1,2,3,4,");
fseek(stdout, -1, SEEK_CUR);
fprintf(stdout, ")");
要实现:
1、2、3、4)
而非
1、2、3、4,)
不幸的是,我输出了后者。
如果stdout
引用的是可寻址流,则可以成功使用fseek
,否则无法使用。
如果程序的标准输出将会被发送到终端或类似设备(通常是默认设置)或管道,则fseek
将失败。如果它将要被发送到文件中,因为您执行了带有重定向输出的程序,则fseek
可以像对任何其他文件一样工作。
每次调用fseek
时,您应该检查其返回值以查看它是否成功或失败。
假定stdout
是可寻址的可能是不好的做法,因为这是一个非常普遍的错误假设。
您的目标是打印一系列具有", "
分隔符的项目,但在第一个项目之前和最后一个项目之后不需要分隔符。既不使用fseek
也不使用打印'\b'
是实现此目标的好方法。而是仅在未刚刚打印完列表中的最后一个项目时才打印逗号。检测这一点可能有些棘手。
但更简单的方法是在每个项目之前加上逗号,除非它是第一个项目。您不能总是知道您正在打印序列的最后一个值。您可以始终知道您是否正在打印第一个值。
伪代码:
bool is_first_item = true
for each item
if is_first_item
is_first_item = false
else
print ", "
end if
print item
end for
stdout
被重定向到管道时,寻找并不一定会失败。据推测,这在我的简短测试中是有效的,因为输出仍然停留在缓冲区中。 - Nisse Engströmfseek
无法在stdout
上使用。相反,您可以使用退格字符'\b'
将光标向后移动一个空格:
fprintf(stdout, "1,2,3,4,");
fprintf(stdout, "\b)");
stdout
指向终端并且没有被重定向到文件或管道时,这将仅仅起作用。此外,如果光标当前位于行的开头,则不能保证其有效。一般来说,只有少数情况下才能使用此功能。stdout
指向终端或者打印\b
字符会移动光标是没有根据的。如果程序输出被重定向到一个文件,那么你只是把"1,2,3,4,\b"
写入那个文件而已。请注意不要改变原意。 - Keith Thompsonstdout
要发送到管道呢? - Keith Thompson'\b'
是否可以合理替代 fseek
调用并不明确(即使问题中的 fseek
能够工作,这种方法是否合理也不确定)。 - Keith Thompson
printf(...)
相当于并且更清晰地表达了fprintf(stdout, ...)
。 - Keith Thompson