Como manter a janela do console aberta no Visual C ++?

191

Estou começando no Visual C ++ e gostaria de saber como manter a janela do console.

Por exemplo, este seria um aplicativo típico "olá mundo":

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World";
    return 0;
}

Qual é a linha que estou perdendo?

Raúl Roa
fonte
Amruth A. Pillai, seu código não mostra "pressione qualquer tecla para continuar" obrigado
Você pode imprimir isso sozinho com uma simples chamada std :: cout.
Raúl Roa
5
A desvantagem de todas as soluções propostas é que nenhuma delas funciona com depuração (Ctrl + F5 falha aqui) e quando o aplicativo para inesperadamente (todos os pontos de interrupção ou leituras de stdin no retorno principal falham aqui). O que eu gostaria de ver é uma janela de console no IDE, como o Eclipse e outros IDEs. Eles simplesmente continuam mostrando a saída para stdout / stderr após o término do programa.
dr. Sybren
@sybren A resposta aceita funciona com CTRL + F5, e por que você deseja uma solução que funcione com depuração (F5)? Certamente, o ponto principal da depuração é .. depurar? Qual é o benefício de ter um console em pausa após o encerramento do programa, em uma sessão de depuração?
JBentley
2
O @JBentley Eclipse e outros IDEs permitem que você leia a saída do programa mesmo após o término do processo. Certamente você vê o benefício adicional, especialmente ao tentar encontrar um bug? Além disso, um ponto de interrupção funciona apenas quando você sabe onde o programa está terminando, o que pode ser difícil de dizer quando a saída desaparece da tela.
dr. Sybren

Respostas:

389

Inicie o projeto em Ctrl+F5vez de apenasF5 .

A janela do console agora ficará aberta com o Press any key to continue . . . mensagem após a saída do programa.

Observe que isso requer a Console (/SUBSYSTEM:CONSOLE)opção vinculador, que você pode ativar da seguinte maneira:

  1. Abra seu projeto e acesse o Solution Explorer. Se você está acompanhando comigo na K&R, sua "Solução" será 'olá' com 1 projeto abaixo, também 'olá' em negrito.
  2. Clique com o botão direito do mouse em 'olá' (ou qualquer que seja o nome do seu projeto.)
  3. Escolha "Propriedades" no menu de contexto.
  4. Escolha Propriedades de configuração> Vinculador> Sistema.
  5. Para a propriedade "Subsistema" no painel direito, clique na caixa suspensa na coluna direita.
  6. Escolha "Console (/ SUBSYSTEM: CONSOLE)"
  7. Clique em Aplicar, aguarde o término do processo e clique em OK. (Se "Aplicar" estiver acinzentado, escolha outra opção de subsistema, clique em Aplicar e volte e aplique a opção de console. Minha experiência é que o OK por si só não funcionará.)

CTRL-F5 e as dicas do subsistema trabalham juntas; eles não são opções separadas.

(Cortesia de DJMorreTX de http://social.msdn.microsoft.com/Forums/en-US/vcprerelease/thread/21073093-516c-49d2-81c7-d960f6dc2ac6 )

Zoidberg
fonte
36
Isso executa o programa sem depuração; é melhor ter uma solução que funcione nos modos de depuração e de execução comum.
スーパーファミコン
3
Para quem não consegue que essa solução funcione em um projeto de makefile, isso ocorre devido a um erro no Visual Studio. Acabei de postar uma resposta com a correção.
JBentley
1
Pode confirmar! Tinha um aplicativo de console que não funcionava e fazia isso. Você não precisa alterar seu código cin.get(),getchar(), system("pause")nem com nenhum outro lixo. Mudar isso funciona.
Callat
Ctrl + F5 significa 'Iniciar sem depuração'. Portanto, você não pode usar isso ao depurar. Basta adicionar system("pause");no final do seu código. Faz sentido e funciona bem.
Milad
41

A maneira padrão é cin.get()antes da sua declaração de retorno.

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World";
    cin.get();
    return 0;
}
Gordon Wilson
fonte
4
Eu sei que, como o programa já está usando o cout, ele já foi resolvido, mas acho que vale a pena mencionar que você precisará # incluir <iostream> e usar o namespace std: std :: cin.get () .
Brian
7
Isso funciona, mas o Ctrl + F5 é muito melhor, especialmente quando o rastreamento destruição objeto global, etc.
ternário
8
-1 para _tmain. Eu votaria outro -1 no cin.get()lugar de colocar um ponto de interrupção no F5 ou usar Ctrl F5. Mas eu tenho apenas um voto negativo.
Saúde e hth. - Alf
8
@ Cheers: O que há de errado _tmain? Essa é a maneira padrão de escrever um aplicativo Windows direcionado ao subsistema Console. Desviar-se desse padrão é o que seria uma má prática. Claramente, ninguém está falando sobre código portátil aqui; a pergunta diz Visual C ++ e _tmainé a assinatura que aparece no código de exemplo. É hora de desistir dessa religião. O Windows é "não padrão" por padrão, e há boas razões para seguir seus padrões.
Cody Gray
8
@CodyGray: Meu voto negativo _tmainé porque é totalmente não-padrão desnecessário (o padrão internacional C ++ exige uma mainplanilha) e porque usa o Tesquema macro da Microsoft , que é uma complicação desnecessária e palavreado para dar suporte ao Windows 9x. Se você se sentir diferente do padrão é uma má prática, não use absolutamente tmain. Não há boas razões para usar tmain, exceto trolling ou, para profissionais, demonstrar total incompetência.
Saúde e hth. - Alf
24

Coloque um ponto de interrupção na returnlinha.

Você está executando no depurador, certo?

Sam Harwell
fonte
15
na maioria das vezes difícil, porque pode haver vários pontos de saída dentro do programa
volzotan
O programa pode não iniciar devido a falta DLL, e nunca bater esse ponto de interrupção
Michael
17

Outra opção é usar

#include <process.h>
system("pause");

Embora isso não seja muito portátil, pois funcionará apenas no Windows, mas imprimirá automaticamente

Pressione qualquer tecla para continuar...

Marcos Marin
fonte
1
system ("pause") Manterá seu processador funcionando, não deve ser usado. Use cin.get () ou equivalente.
Krythic
systemé declarado em <stdlib.h>.
Melpomene
@ Krythic Eu apenas tentei e não comia 100% da CPU. O uso do meu processador foi de 0% a 1% o tempo todo. Não pode se reproduzir.
Melpomene
O sistema ("pausa") chamará o comando "pausa" no cmd, que NÃO usa a CPU o tempo todo. É equivalente a _getche () essencialmente.
Paul Stelian
7

Para projetos de makefile, a solução aceita falha, devido a um erro no Visual Studio (que está presente pelo menos até a versão 2012 - ainda não testei 2013). Este bug é detalhado aqui .

Para que o console seja pausado após o término do programa em um projeto de makefile, execute estas etapas (isso pode ser diferente para versões diferentes de 2010 - 2012):

1) Passe /SUBSYSTEM:CONSOLEpara o vinculador. - EDIT : veja abaixo.

2) Abra seu arquivo de projeto (.vcxproj) em um editor de texto.

3) Dentro da <project>marca raiz , insira o seguinte:

<ItemDefinitionGroup>
  <Link>
    <SubSystem>Console</SubSystem>
  </Link>
</ItemDefinitionGroup>

4) Recarregue o projeto na sua solução.

5) Execute o programa sem depuração (CTRL + F5).

EDITAR:

Conforme meu comentário abaixo, definir a opção de vinculador /SUBSYSTEM:CONSOLEé realmente irrelevante para projetos de makefile (e nem sempre é possível, se você estiver usando um compilador que não seja o MSVC). O que importa é que a configuração seja adicionada ao arquivo .vcxproj, conforme a etapa 3 acima.

JBentley
fonte
Eu nunca ouvi falar desse passo 3 antes. Tem certeza de que é necessário e funciona?
Mooing Duck
@mooingduck Sim, e depois dos meus comentários sobre sua resposta aqui , agora descobri que passar /SUBSYSTEM:CONSOLEpara o vinculador é realmente irrelevante - a etapa 3 é tudo o que importa. Lembre-se de que minha resposta está relacionada a projetos makefile - em um projeto makefile, o IDE não tem como saber o que você está passando para o vinculador (talvez você nem esteja usando um compilador que tem uma /SUBSYSTEM:CONSOLEopção), e é o projeto próprio que controla se deve ou não ser um programa de console. Vou editar minha resposta de acordo.
JBentley 28/05
1
@mooingduck Também posso confirmar que uso essa solução em um projeto makefile, com SCons como o sistema de compilação e MSVC e MinGW como compiladores. Não há outra maneira que eu conheça para fazer com que o IDE pause o console após o término no modo sem depuração.
JBentley 28/05
1
@chuckleplant Acho que não, meu fluxo de trabalho foi o contrário, ligando para SCons do VS. Inicialmente, criei manualmente meus projetos de makefile do VS para que eles passassem variáveis ​​de configuração para o script do SCons (por exemplo, 32/64 bits, nome do compilador, release / debug), que depois lidaram com o restante da lógica. Nessa configuração, não havia necessidade de os arquivos do projeto mudarem, então eu não usei nenhum recurso de geração automática de SCons. Desde então, mudei para o Linux para não usar mais o VS. Como é um bug do VS, pode valer a pena enviar uma solicitação de recurso aos SCons para lidar com a etapa extra necessária.
JBentley
1
Como alternativa, você pode incluir apenas algum código Python no script SCons para fazer isso sempre que um arquivo de projeto for gerado. Acredito que os arquivos do projeto VS estejam em conformidade com o padrão XML, portanto, deve ser bastante fácil adicionar os elementos ausentes e exigir apenas algumas linhas de código. Eu sugeriria começar aqui (para Python 2.x) ou aqui (3.x). Essa resposta também pode ser interessante.
JBentley
4

Você pode usar cin.get();ou cin.ignore();imediatamente antes da sua declaração de retorno para evitar que a janela do console se feche.

CMS
fonte
4

basta colocar um ponto de interrupção no último colchete do main.

    int main () {
       //...your code...
       return 0;
    } //<- breakpoint here

funciona para mim, não há necessidade de executar sem depuração. Ele também executa destruidores antes de atingir o ponto de interrupção, para que você possa verificar se há alguma mensagem impressa nesses destruidores.

Juan Castano
fonte
3

Basta adicionar um ponto de interrupção ao colchete de fechamento do seu _tmainmétodo. Essa é a maneira mais fácil, e você não precisa adicionar código para depurar.

Odys
fonte
2

Coloque um ponto de interrupção na chave final de main(). Ele disparará mesmo com várias returninstruções. A única desvantagem é que uma ligação para exit()não será atendida.

Se você não estiver depurando, siga os conselhos da resposta de Zoidberg e inicie seu programa com Ctrl+ em F5vez de apenas F5.

Chade
fonte
2

Meus 2 centavos:

Opção 1: adicione um ponto de interrupção no final de main()

Opção 2: adicione esse código, logo antes do return 0;:

std::cout << "Press ENTER to continue..."; //So the User knows what to do
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Você precisa incluir <iomanip>parastd::numeric_limits

Arnav Borborah
fonte
2

basta adicionar system ("pause") no final do código antes de retornar 0 como este

#include <stdlib.h>

int main()
{
    //some code goes here
    system("pause")
    return 0;
}
melpomene
fonte
2
int main()
{
    //...
    getchar();
    return 0;
}
gonnavis
fonte
2

cin.get(), Ou system("PAUSE"). Eu não ouvi você pode usarreturn(0);

Udhav Sarvaiya
fonte
1

Incluo #include <conio.h>e depois adiciono getch();logo antes da return 0;linha. Foi o que aprendi na escola de qualquer maneira. Os métodos mencionados acima aqui são bem diferentes, eu vejo.

Amruth Pillai
fonte
2
-1: Além do fato de que interromper o programa em si geralmente é a solução errada (já que na maioria dos casos não é o comportamento que você deseja que seu binário liberado tenha), o conio.h não é padrão , está desatualizado e é um Cabeçalho C, não C ++! Infelizmente, existem muitas práticas de programação ruins ensinadas nas escolas.
JBentley 28/05
Espera-se que isso seja usado apenas durante o teste, não é algo que você manteria na versão final. Se você está codificando para Windows, qual é o problema com #include <conio.h> / _getch () ;? É mais rápido escrever do que cin.get (), não é necessário pressionar 2 teclas (pelo menos um caractere + enter) e não funciona apenas no modo de depuração ou liberação. O que há de errado então?
quer
1

Teve o mesmo problema. Estou usando _getch()pouco antes da declaração de retorno. Funciona.

Martin
fonte
Você pode adicionar exemplos e explicações ao seu código, especialmente para uma pergunta / resposta feita há muito tempo. Além disso, você responde é funcionalmente idêntico a várias respostas mais antigas e usa a mesma chamada que outra resposta existente.
Clockwork-Muse
0

(Algumas opções podem ser chamadas por nomes diferentes. Eu não uso a versão em inglês)

Eu tive o mesmo problema, quando criei projetos com a opção "projeto vazio", crie projeto como "aplicativo de console Win32" em vez de "projeto vazio". Na caixa de diálogo que aparece agora, você pressiona "continuar" e depois pode marcar a opção "projeto vazio" e pressionar confirmar. Depois disso, CTRL + F5 abrirá um console que não fecha automaticamente.

Blechdose
fonte
0

Eu tive o mesmo problema; No meu aplicativo, há vários pontos exit () e não havia como saber exatamente onde ele sai; então, descobri isso:

atexit(system("pause"));

ou

atexit(cin.get());

Dessa forma, ele irá parar, não importa onde saímos no programa.

Charaf Errachidi
fonte
Nenhuma dessas chamadas válidas para atexit. atexitpega um ponteiro de função, não um número inteiro.
Melpomene
0

Outra opção:

#ifdef _WIN32
#define MAINRET system("pause");return 0
#else
#define MAINRET return 0
#endif

Principalmente:

int main(int argc, char* argv[]) {
    MAINRET;
}
chen_767
fonte
0

Na verdade, a solução real é a seleção do próprio modelo de projeto. É necessário selecionar o aplicativo de console do Win32 no VS antigo ou preencher primeiro o nome do projeto, clicar duas vezes no assistente da área de trabalho do Windows e selecionar o aplicativo de console do Win32. Em seguida, selecione o projeto vazio neste momento. Isso permite o que o questionador original realmente queria sem adicionar um ponto de parada extra e manter o código. Eu também passei por esse problema. A resposta também está no site do MSDN.

user9416431
fonte
0

Aqui está uma maneira de manter a janela de comando aberta, independentemente de como a execução é interrompida sem modificar nenhum código:

No Visual Studio, abra Páginas de propriedades do projeto -> Depuração .

Para Comando , insira$(ComSpec)

Para argumentos de comando , insira/k $(TargetPath) . Anexe todos os argumentos ao seu próprio aplicativo.

Agora, F5 ou Ctrl-F5 executa o Windows / System32 / cmd.exe em uma nova janela e / k garante que o prompt de comando permaneça aberto após a conclusão da execução.

A desvantagem é que a execução não para em pontos de interrupção.

Jonathan Lidbeck
fonte
0

Como alguns já apontaram, a solução Zoidbergs não anexa o depurador, que é algo que você geralmente não deseja.

A melhor opção imo é configurar seu VS de acordo (a partir do VS 2017), acessando Ferramentas> Opções> Depuração> Geral. Lá, desmarque "Feche automaticamente o console quando a depuração parar" (na parte inferior), o que provavelmente está marcado no seu caso.

iko79
fonte
-1

você pode simplesmente colocar keep_window_open (); antes do retorno aqui é um exemplo

int main()
{
    cout<<"hello world!\n";
    keep_window_open ();
    return 0;
}
Sifis Babionitakis
fonte
2
De onde vem keep_window_open (), por exemplo, qual arquivo de cabeçalho e biblioteca?
Tom Goodfellow
seu deste std_lib_facilities.h mas na maioria das vezes você o inclui
Sifis Babionitakis 15/10/1919