Saturday 19 August 2017

Freopen Stdin Binary Options


Eu quero reabrir os handles de arquivo stdin e stdout (e talvez stderr enquanto estou com ele), para que futuras chamadas para printf () ou putchar () ou puts () vá para um arquivo e futuras chamadas para getc () e such Virá de um arquivo. 1) Eu não quero perder permanentemente entrada / saída / erro padrão. Posso querer reutilizá-los mais tarde no programa. 2) Eu não quero abrir novos endereços de arquivo porque esses arquivos devem ser passados ​​em torno de um lote ou global (shudder). 3) Eu não quero usar qualquer open () ou fork () ou outras funções dependentes do sistema se eu não posso ajudá-lo. Então, basicamente, ele funciona para fazer isso: E, se ele faz, como posso obter o valor original de stdin de volta Eu tenho que armazená-lo em um arquivo e apenas obtê-lo de volta mais tarde Por que usar freopen (). A especificação C89 tem a resposta em uma das notas finais para a seção sobre ltstdio. hgt: 116. O uso principal da função freopen é alterar o arquivo associado a um fluxo de texto padrão (stderr. Stdin ou stdout), como aqueles Os identificadores não precisam ser valores modificáveis ​​para os quais o valor retornado pela função fopen pode ser atribuído. Freopen é usualmente mal utilizado, e. Stdin freopen (newin, r, stdin). Este não é mais portátil do que fclose (stdin) stdin fopen (newin, r). Ambas as expressões tentam atribuir a stdin. Que não é garantido para ser atribuível. A maneira correta de usar o freopen é omitir a atribuição: freopen (newin, r, stdin) Esclarecimento: Atribuição sintática ao stdin. Como em stdin fopen (.) Ou stdin freopen (.). Não é portátil, porque stdin é permitido para ser uma macro. Stdio. h pode conter definir stdin builtingetstdin (). E claro que você não pode colocar isso no LHS de uma tarefa. ChrisLutz, a maneira correta de usar freopen é simplesmente if (freopen (quotnewinquot, quotrquot, stdin) NULL). --- o valor de retorno é útil para indicar se o aberto falhou, mas você shouldn39t geralmente precisa atribuí-lo a qualquer coisa. Ndash Quuxplusone Dez 19 13 at 18:06 A função dup2 () deve fornecer o que você precisa (se não referências para exatamente o que você precisa). Mais especificamente, você pode dup2 () o descritor de arquivo stdin para outro descritor de arquivo, fazer outras coisas com stdin e, em seguida, copiá-lo quando quiser. A função dup () duplica um descritor de arquivo aberto. Especificamente, ele fornece uma interface alternativa para o serviço fornecido pela função fcntl () usando o valor de comando constante FDUPFD, com 0 para seu terceiro argumento. O descritor de arquivo duplicado compartilha qualquer bloqueio com o original. Em caso de sucesso, dup () retorna um novo descritor de arquivo que tem o seguinte em comum com o original: Mesmo arquivo aberto (ou pipe) Mesma ponteiro de arquivo (os dois descritores de arquivo compartilham um ponteiro de arquivo) Mesmo modo de acesso (ler, escrever ou ler) / Write) respondeu Feb 25 09 at 6:22 A pergunta explicitamente diz não usar funções dependentes do sistema, no entanto. Ndash desenrolar Feb 25 09 at 6:55 E a pergunta diz explicitamente limitar o de abrir córregos / descritores de arquivo ndash Tim Post 9830 Feb 25 09 at 15:23 Isso picos a agulha no meu round-peg-square-hole-o-meter , O que você está tentando realizar Lembre-se que stdin, stdout e stderr são descritores de arquivo 0, 1 e 2 para cada processo recém-criado. Freopen () deve manter o mesmo fds, basta atribuir novos fluxos para eles. Então, uma boa maneira de garantir que isso realmente está fazendo o que você quer que ele faça seria: Eu acredito que este é o comportamento esperado do freopen (), como você pode ver, você ainda está usando apenas três descritores de arquivos (e fluxos associados) . Isso anularia qualquer redirecionamento de shell, pois não haveria nada para o shell redirecionar. No entanto, seu provavelmente vai quebrar tubos. Você pode querer ter certeza de configurar um manipulador para SIGPIPE, no caso de seu programa encontra-se na extremidade de bloqueio de um pipe (não FIFO, pipe). Assim. / Yourprogram --stdout /tmp/stdout. txt --stderr /tmp/stderr. txt deve ser facilmente realizado com freopen () e mantendo os mesmos descritores de arquivos reais. O que eu não entendo é porque youd necessidade de colocá-los de volta uma vez mudá-los Certamente, se alguém aprovou qualquer opção, eles iriam querer persistir até que o programa terminou respondido Feb 25 09 at 15:31 Hi Tim. Tive problemas com a entrada de comentários no meu último post. Ele doesn39t como copy39n39paste por algum motivo. Queria ir para listar a saída e dar detalhes sys mas ele foi enviado antes que eu estivesse pronto. As duas primeiras instruções fazem como se poderia esperar, no entanto, a final e isso deve ir para a tela novamente. Compilação I39m no XCode clang 500.2.79 no Mac OS X 10.9.5. Eu até tentei reabrir stdout em / dev / tty também sem alegria. É como se uma vez que o stdout foi redefinido, o jogo terminou. Ndash VectorVictor May 29 at 12:55 Esta é uma versão modificada do método Tim Posts que usei / dev / tty em vez de / dev / stdout. Eu não sei por que não funciona com stdout (que é um link para / proc / self / fd / 1): Usando / dev / tty a saída é redirecionada para o terminal de onde o aplicativo foi lançado. Espero que esta informação é útil. Freopen resolve a parte mais fácil. Manter o stdin velho ao redor não é duro se você havent leu qualquer coisa e se você estiver disposto usar chamadas de sistema de POSIX como o dup ou o dup2. Se você começou a ler a partir dele, todas as apostas estão desligadas. Talvez você possa nos dizer o contexto em que esse problema ocorre Id incentivá-lo a furar a situações onde você está disposto a abandonar stdin stdout e stdout e, portanto, pode usar freopen. Respondeu Feb 25 09 at 6:27 No contexto, eu acho que eu poderia fugir com o abandono do stdin / stdout velho se eu realmente tivesse que. I39m tentando adicionar ao meu programa uma opção para o programa para redirecionar stdin e stdout em si, para as pessoas que estão executando o programa e don39t sabe muito bem a sua shell. Apenas para o inferno. Ndash Chris Lutz Feb 25 09 at 6:40 Meus alunos definitivamente têm problemas com o redirecionamento de E / S, para que seu objetivo som como um bom. Talvez você fique melhor com opções de linha de comando - i e - o para nomear arquivos de entrada e saída ndash Norman Ramsey Feb 25 09 at 6: 43fopen (3) - Página de man do Linux fopen, fdopen, freopen - A função fopen () abre o arquivo cujo nome é a seqüência de caracteres apontada pelo caminho e associa um fluxo com ele (veja a seção featuretestmacros (7)): fdopen O modo de argumento aponta para uma seqüência de caracteres que começa com uma das seguintes seqüências (possivelmente seguida de caracteres adicionais, conforme descrito abaixo): r Abra o arquivo de texto para leitura. O fluxo é posicionado no início do arquivo. Aberto para leitura e escrita. O fluxo é posicionado no início do arquivo. Truncar o arquivo para zero comprimento ou criar arquivo de texto para gravação. O fluxo é posicionado no início do arquivo. Aberto para ler e escrever. O arquivo é criado se ele não existir, caso contrário, ele será truncado. O fluxo é posicionado no início do arquivo. Abrir para anexar (gravação no final do arquivo). O arquivo é criado se ele não existir. O fluxo é posicionado no final do arquivo. Abrir para leitura e anexação (gravação no final do arquivo). O arquivo é criado se ele não existir. A posição do arquivo inicial para leitura está no início do arquivo, mas a saída é sempre anexada ao final do arquivo. A seqüência de caracteres de modo também pode incluir a letra b como um último caractere ou como um caractere entre os caracteres em qualquer uma das seqüências de dois caracteres descritas acima. Isto é estritamente para compatibilidade com C89 e não tem nenhum efeito o b é ignorado em todos os sistemas conformes POSIX, incluindo Linux. (Outros sistemas podem tratar arquivos de texto e arquivos binários de forma diferente, e adicionar o b pode ser uma boa idéia se você fizer E / S para um arquivo binário e esperar que seu programa pode ser portado para ambientes não-UNIX). Detalhes das extensões glibc para o modo. Qualquer arquivo criado terá o modo SIRUSR SIWUSR SIRGRP SIWGRP SIROTH SIWOTH (0666), conforme modificado pelo valor do umask dos processos (veja umask (2)). Leituras e gravações podem ser intercaladas em fluxos de leitura / gravação em qualquer ordem. Observe que ANSI C requer que uma função de posicionamento de arquivo intervir entre saída e entrada, a menos que uma operação de entrada encontre fim de arquivo. (Se esta condição não for satisfeita, então uma leitura é permitida retornar o resultado de escritas que não seja a mais recente.) Portanto, é uma boa prática (e às vezes mesmo necessário sob Linux) colocar um fseek (3) ou fgetpos (3 ) Entre operações de escrita e leitura em tal fluxo. Esta operação pode ser uma aparente não-op (como em fseek (. 0L, SEEKCUR) chamado para o seu efeito secundário de sincronização. Abrir um arquivo no modo de anexar (a como o primeiro caractere de modo) faz com que todas as operações de gravação subseqüentes para este fluxo para Ocorre no final do arquivo, como se precedesse a chamada: A função fdopen () associa um fluxo ao descritor de arquivo existente, fd. O modo do fluxo (um dos valores r, r, w, w, a, A) deve ser compatível com o modo do descritor de arquivo. O indicador de posição de arquivo do novo fluxo é definido como aquele que pertence a fd e os indicadores de erro e fim de arquivo são apagados. Modos w ou w não causam truncamento O arquivo de descrição não é enganado, e será fechado quando o fluxo criado por fdopen () é fechado. O resultado de aplicar fdopen () a um objeto de memória compartilhada é indefinido. A função freopen () abre o arquivo cuja Name é a seqüência apontada pelo caminho e associa o fluxo apontado por stream com ele. O fluxo original (se existir) é fechado. O argumento mode é usado como na função fopen (). O uso principal da função freopen () é alterar o arquivo associado a um fluxo de texto padrão (stderr. Stdin ou stdout). Valor de retorno Após a conclusão bem-sucedida fopen (), fdopen () e freopen () retornam um ponteiro FILE. Caso contrário, NULL é retornado e errno é definido para indicar o erro. O modo fornecido para fopen (), fdopen () ou freopen () era inválido. As funções fopen (), fdopen () e freopen () também podem falhar e definir errno para qualquer um dos erros especificados para o malloc de rotina (3). A função fopen () também pode falhar e definir errno para qualquer um dos erros especificados para a rotina aberta (2). A função fdopen () também pode falhar e definir errno para qualquer um dos erros especificados para a rotina fcntl (2). A função freopen () também pode falhar e definir errno para qualquer um dos erros especificados para as rotinas open (2), fclose (3) e fflush (3). Conforming To As funções fopen () e freopen () estão em conformidade com C89. A função fdopen () está em conformidade com POSIX.1-1990. Notas do Glibc A biblioteca GNU C permite as seguintes extensões para a seqüência de caracteres especificada no modo. C (desde a glibc 2.3.3) Não faça a operação aberta, ou operações subseqüentes de leitura e gravação, pontos de cancelamento de thread. Este sinalizador é ignorado para fdopen (). E (desde a glibc 2.7) Abra o arquivo com o sinalizador OCLOEXEC. Consulte open (2) para obter mais informações. Este sinalizador é ignorado para fdopen (). M (desde glibc 2.3) Tentativa de acessar o arquivo usando mmap (2), em vez de I / O chamadas do sistema (read (2), write (2)). Atualmente, o uso de mmap (2) é apenas tentado para um arquivo aberto para leitura. X Abra o arquivo exclusivamente (como o sinalizador OEXCL de open (2)). Se o arquivo já existir, fopen () falha e define errno como EEXIST. Este sinalizador é ignorado para fdopen (). Além dos caracteres acima, fopen () e freopen () suportam a seguinte sintaxe no modo. A string dada é tomada como o nome de um conjunto de caracteres codificados eo fluxo é marcado como wide-oriented. Em seguida, as funções de conversão internas convertem I / O para e a partir da seqüência de caracteres definida. Se a sintaxe de seqüência de caracteres ccs não for especificada, a orientação ampla do fluxo será determinada pela primeira operação de arquivo. Se essa operação é uma operação de caracteres largos, o fluxo é marcado de forma ampla e as funções para converter para o conjunto de caracteres codificados são carregadas. Ao analisar para caracteres de sinalização individuais no modo (ou seja, os caracteres que precedem a especificação ccs), a implementação glibc de fopen () e freopen () limita o número de caracteres examinados em modo para 7 (ou, nas versões glibc antes de 2.14, para 6 , O que não foi suficiente para incluir possíveis especificações como rbcmxe). A implementação atual de fdopen () analisa no máximo 5 caracteres no modo. Referido ByObra o arquivo cujo nome é especificado no nome do arquivo do parâmetro e o associa a um fluxo que pode ser identificado em operações futuras pelo ponteiro FILE retornado. As operações permitidas no fluxo e como elas são executadas são definidas pelo parâmetro mode. O fluxo retornado é totalmente armazenado em buffer por padrão se ele é conhecido por não se referir a um dispositivo interativo (consulte setbuf). O ponteiro retornado pode ser disassociated do arquivo chamando fclose ou freopen. Todos os arquivos abertos são automaticamente fechados no término do programa normal. O ambiente em execução suporta pelo menos arquivos FOPENMAX abertos simultaneamente. Parâmetros filename C string contendo o nome do arquivo a ser aberto. Seu valor deve seguir as especificações de nome de arquivo do ambiente em execução e pode incluir um caminho (se suportado pelo sistema). Mode C string contendo um modo de acesso a arquivos. Pode ser: read: Abrir arquivo para operações de entrada. O arquivo deve existir. Write: Criar um arquivo vazio para operações de saída. Se um arquivo com o mesmo nome já existir, seu conteúdo será descartado eo arquivo será tratado como um novo arquivo vazio. Anexar: Abrir o arquivo para saída no final de um arquivo. As operações de saída sempre gravam dados no final do arquivo, expandindo-o. As operações de reposicionamento (fseek, fsetpos, rebobinagem) são ignoradas. O arquivo é criado se ele não existir. Leitura / atualização: Abra um arquivo para atualização (tanto para entrada e saída). O arquivo deve existir. Escrever / atualizar: Criar um arquivo vazio e abri-lo para atualização (tanto para entrada e saída). Se um arquivo com o mesmo nome já existe, seu conteúdo é descartado eo arquivo é tratado como um novo arquivo vazio. Anexar / atualizar: Abra um arquivo para atualização (tanto para entrada e saída) com todas as operações de saída escrevendo dados no final do arquivo. As operações de reposicionamento (fseek, fsetpos, rebobinar) afetam as operações de entrada seguintes, mas as operações de saída movem a posição de volta ao final do arquivo. O arquivo é criado se ele não existir. Com os especificadores de modo acima, o arquivo está aberto como um arquivo de texto. Para abrir um arquivo como um arquivo binário. Um caractere b tem que ser incluído na seqüência de modo. Este caractere b adicional pode ser anexado no final da string (tornando assim os seguintes modos compostos: rb, wb, ab, rb, wb, ab) ou ser inserido entre a letra eo sinal para os modos mistos (rb, Wb, ab). O novo padrão C (C2011, que não faz parte de C) adiciona um novo subespecificador padrão (x), que pode ser anexado a qualquer especificador w (para formar wx. Wbx. Wx ou wbx / wbx). Essa subespecifica força a função a falhar se o arquivo existir, em vez de substituí-lo. Se os caracteres adicionais seguirem a seqüência, o comportamento dependerá da implementação da biblioteca: algumas implementações podem ignorar caracteres adicionais, de forma que, por exemplo, um t adicional (às vezes usado para indicar explicitamente um arquivo de texto) seja aceito. Em algumas implementações de biblioteca, abrir ou criar um arquivo de texto com modo de atualização pode tratar o fluxo em vez disso como um arquivo binário. Os arquivos de texto são arquivos que contêm seqüências de linhas de texto. Dependendo do ambiente em que o aplicativo é executado, pode ocorrer alguma conversão de caracteres especiais em operações de entrada / saída no modo de texto para adaptá-las a um formato de arquivo de texto específico do sistema. Embora em alguns ambientes não ocorram conversões e os arquivos de texto e os arquivos binários sejam tratados da mesma maneira, o uso do modo apropriado melhora a portabilidade. Para arquivos abertos para atualização (aqueles que incluem um sinal), nos quais as operações de entrada e saída são permitidas, o fluxo deve ser liberado (fflush) ou reposicionado (fseek, fsetpos, rebobinar) antes de uma operação de leitura que segue uma operação de escrita. O fluxo deve ser reposicionado antes de uma operação de escrita que segue uma operação de leitura (sempre que essa operação não atingiu o fim do arquivo). Valor de retorno Se o arquivo for aberto com êxito, a função retornará um ponteiro para um objeto FILE que pode ser usado para identificar o fluxo em operações futuras. Caso contrário, um ponteiro nulo é retornado. Na maioria das implementações da biblioteca, a variável errno também é definida como um código de erro específico do sistema em caso de falha.

No comments:

Post a Comment