我知道每个人都告诉我使用fgets而不是因为缓冲区溢出而得到的.但是,我对第三个参数感到有点困惑fgets().据我了解,fgets依赖于:
char * fgets ( char * str, int num, FILE * stream );
Run Code Online (Sandbox Code Playgroud)
char* str 是我的输入将存储在哪里的ptr.
num 是要读取的最大字符数.
但是什么FILE *stream?如果我只是提示用户输入字符串(如句子),我应该输入" stdin"吗?
我应该键入FILE *stdin顶部,靠近main()吗?
我有以下Python脚本,如果输入不是数字,则读取数字并输出错误.
import fileinput
import sys
for line in (txt.strip() for txt in fileinput.input()):
if not line.isdigit():
sys.stderr.write("ERROR: not a number: %s\n" % line)
Run Code Online (Sandbox Code Playgroud)
如果我从stdin获得输入,我必须按Ctrl+ D 两次才能结束程序.为什么?
当我自己运行Python解释器时,我只需要按Ctrl+ D一次.
bash $ python test.py
1
2
foo
4
5
<Ctrl+D>
ERROR: not a number: foo
<Ctrl+D>
bash $
Run Code Online (Sandbox Code Playgroud) 我基本上想测试stdin是否有输入(如果你回显并管道它).我找到了有效的解决方案,但它们很难看,而且我喜欢我的解决方案.
在linux上我用这个:
bool StdinOpen() {
FILE* handle = popen("test -p /dev/stdin", "r");
return pclose(handle) == 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道我应该添加更多的错误处理,但除此之外.
在Windows上我用这个:
bool StdinOpen() {
static HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
DWORD bytes_left;
PeekNamedPipe(handle, NULL, 0, NULL, &bytes_left, NULL);
return bytes_left;
}
Run Code Online (Sandbox Code Playgroud)
对于linux来说这很好,但我想知道在不使用管道的情况下我可以调用的等效API(就像test -f $file你一样fopen($file, "r") != NULL).我有能力open("/dev/stdin", "r")和做同样的事情,但我想知道最好的方法.
简介:我想知道可以用来代替test -p /dev/stdinlinux 的API ,如果你知道一个更好的Windows解决方案.
我有十几个可以通过stdin或选项接受输入的程序,我想以类似的方式为输出实现相同的功能.
optparse代码如下所示:
parser.add_option('-f', '--file',
default='-',
help='Specifies the input file. The default is stdin.')
parser.add_option('-o', '--output',
default='-',
help='Specifies the output file. The default is stdout.')
Run Code Online (Sandbox Code Playgroud)
其余适用的代码如下所示:
if opts.filename == '-':
infile = sys.stdin
else:
infile = open(opts.filename, "r")
if opts.output == '-':
outfile = sys.stdout
else:
outfile = open(opts.output, "w")
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常,我喜欢它的简单性 - 但是我无法找到任何使用默认值' - '表示stdout的人的引用.这是一个很好的一致解决方案还是我忽略了更好或更期望的事情?
我正试图通过面试街学习二郎.我现在只是学习这门语言所以我什么都不知道.我想知道如何从stdin读取并写入stdout.
我想写一个写"Hello World!"的简单程序.stdin收到的次数.
所以用stdin输入:
6
Run Code Online (Sandbox Code Playgroud)
写到标准输出:
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Run Code Online (Sandbox Code Playgroud)
理想情况下,我会一次读取stdin一行(即使在这种情况下它只是一位数)所以我想我将使用get_line.这就是我现在所知道的.
谢谢
谢谢
我试图在Windows 7 64位和Python 3.4.3上异步读取stdin
我尝试了这个受到SO回答的启发:
import asyncio
import sys
def reader():
print('Received:', sys.stdin.readline())
loop = asyncio.get_event_loop()
task = loop.add_reader(sys.stdin.fileno(), reader)
loop.run_forever()
loop.close()
Run Code Online (Sandbox Code Playgroud)
然而,它提出了一个OSError: [WInError 100381] An operation was attempted on something that is not a socket.
类似文件的对象是否stdin可以包含在类中以赋予它套接字的API?我已单独提出这个问题,但如果解决方案很简单,请在此处回答.
假设我无法包装类似文件的对象使其成为套接字,我尝试使用流作为这个要点的启发:
import asyncio
import sys
@asyncio.coroutine
def stdio(loop):
reader = asyncio.StreamReader(loop=loop)
reader_protocol = asyncio.StreamReaderProtocol(reader)
yield from loop.connect_read_pipe(lambda: reader_protocol, sys.stdin)
@asyncio.coroutine
def async_input(loop):
reader = yield from stdio(loop)
line = yield from reader.readline()
return …Run Code Online (Sandbox Code Playgroud) 我该如何立即输出stdout?stdout所有输入完成后将打印.
require 'open3'
def run(cmd)
Open3.popen3(cmd) do |stdin, stdout, stderr, thread|
Thread.new do
stdout.each {|l| puts l}
end
Thread.new do
while thread.alive?
stdin.puts $stdin.gets
end
end
thread.join
end
end
run ("ruby file_to_test.rb")
Run Code Online (Sandbox Code Playgroud)
file_to_test.rb:
puts "please, enter s"
puts "please, enter q"
s = gets.chomp!
q = gets.chomp!
puts s
puts q
Run Code Online (Sandbox Code Playgroud)
运行main.rb后的结果是:
somestring
somestring2
please, enter s
please, enter q
somestring
somestring2
Run Code Online (Sandbox Code Playgroud)
我该如何立即输出stdout?
我想创建一个从STDIN静默读取密码的Java程序.我的意思是,不向终端输出任何按下的字符,并将其隐藏在命令行历史记录和操作系统进程列表中ps.
如果调用fclose(0),这会关闭stdin吗?
我问这个的原因是由于某种原因,stdin在我的应用程序中被关闭,我无法弄清楚为什么.我检查了fclose(stdin),这不在应用程序中,所以我想知道fclose(0)是否会导致未定义的行为,例如关闭stdin?
如果没有,stdin可能被错误关闭的其他方式是什么?
我正试图从蒂姆斯在线评判中解决这个问题.要解决此问题,您需要生成一个包含1 000 000个小写拉丁字母的序列,并在1秒内将其写入标准输入.
使用C++或Java很容易解决这个问题.我这里有python解决方案:
import os
from random import randint
s = ''.join(chr(97 + randint(0, 25)) for i in range(1000000))
os.write(1, bytes(s, 'utf8'))
Run Code Online (Sandbox Code Playgroud)
需要1.7秒:
$ time python3.3 1219.py > /dev/null
real 0m1.756s
user 0m1.744s
sys 0m0.008s
Run Code Online (Sandbox Code Playgroud)
我得到了"超出时间限制"的结果.所以问题是"如何更快地做到这一点?"
UPD1:使用randint(97, 122)减少16ms的时间.现在是1.740s
UPD2: @Martijn Pieters的解决方案需要0.979秒,但它也没有通过测试.
UPD3 Martijn Pieters提出了一个非常好的解决方案,但它仍然很慢:
from sys import stdin
from random import choice
from string import ascii_lowercase
s = ''.join([choice(ascii_lowercase) for _ in range(1000000)])
stdout.write(s)
Run Code Online (Sandbox Code Playgroud)
需要0.924秒
from sys import stdout
from random import …Run Code Online (Sandbox Code Playgroud)