Ir ao conteúdo
  • Cadastre-se

C++ Ler linha do CMD


Ywill

Posts recomendados

Olá, preciso de uma orientação, após pesquisar não encontrei algo que possibilite a leitura de uma linha já escrita no CMD. Existe alguma biblioteca, função que eu consiga usar?

No caso eu tenho um programa que lista um diretório e me movo através dele pelas setas, preciso que ele pegue a linha selecionada e passe para uma variável string assim posso abrir esse arquivo selecionado.

void listar_Produto()
{
system("MODE con cols=168 lines=60");
DIR *dir;
struct dirent *entry;
/*
    struct dirent{
        long d_ino;
        ...
        char d_name[PATH_MAX+1]
    }
Dirent é um struct do proprio sistema contendo essas variaveis pré declaradas
o que nos permite chamar o d_name com o entry
entry é um ponteiro na memória que liga a dirent
entry->d_name
*/
int i = 0;
size_t count = 0;
/*
    Usado para indexar o array que contaremos quanta arquivos temos
*/
//Abre o diretorio para preparar para listagem
    if ((dir = opendir("C:/db_NoSQL/produtos/")) == NULL)
    perror("opendir() error");
    int li=0,tecla;
    puts("      Produtos cadastrados");
        do
        {
            while ((entry = readdir(dir)) != NULL)
/*
    declara a variavel entry para receber o readddir de do dir e se for difrente de NULL
    ou seja, enquanto arquivo existir (for diferente de nulo) faça
*/
            if ( strcmp( entry->d_name, "." ) && strcmp( entry->d_name, ".." ) )
            {
                printf("    %zu) - %s\n", count + 1, entry->d_name);
                count++;
            }
            gotoxy(0,li);
            printf("->");
            gotoxy(79,24);
                tecla=0;
                if(kbhit())
                {
                    tecla = getch();
                    gotoxy(0,li);
                    printf("  ");
                    if(tecla==224)
                        tecla = getch();
                    if(tecla == 72)
                        li--;
                    else
                        if(tecla == 80)
                            li++;
                    if(li > count)
//se a linha que estamos percorrendo for maior que count ele volta para linha 0
                        li=0;
                    else
                        if(li < 1)
//se a linha que estamos percorrendo for menor que 1 ele pula para posição total
                            li=count;
                    gotoxy(0,li);
                    printf("->");
                    gotoxy(79,24);/* se não quiser que cursor fique piscando ali */
                    }

                        }while (tecla != 13);
//Quando tecla for igual a ENTER
system("cls");

cout<<li;
//Imprime a linha selecionada, futuramente será usada como index
system("PAUSE");
//Pausa o sistema para podermos visualizar a variavel li
//Essa parte será excluido posteriormente, é apenas para verificação do Index.

                        switch(li)
/*
Após a tecla ENTER ser presionada ele pega o numero armazenado em li e troca para caso
correspondente.
*/
                        {
/*
Agora precisamos fazer com que pelo index pegue o nome do produto(arquivo)
Swtich apenas aceita constant ou seja apenas numeros 1,2,3 etc..
tirar o switch por if talvez.
*/
                            case 1:
printf("    %zu) - %s\n", li);
                        }while(tecla != 27);
}

Como na imagem, quero passar para uma variável string o nome "asd.txt".

cbhard.PNG

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Certo, desculpe a ignorância eu estou tentando implementar, após tentativas o mais perto que cheguei foi receber o ultimo nome(arquivo) da lista em todas as posições do vetor, o código ficou assim:

void listar_Produto()
{
system("MODE con cols=168 lines=60");
DIR *dir;
struct dirent *entry;
/*
    struct dirent{
        long d_ino;
        ...
        char d_name[PATH_MAX+1]
    }
Dirent é um struct do proprio sistema contendo essas variaveis pré declaradas
o que nos permite chamar o d_name com o entry
entry é um ponteiro na memória que liga a dirent
entry->d_name
*/
size_t count = 0;
char *indexar[100] = {"foo"};//Alterei
int j = 0;
/*
    Usado para indexar o array que contaremos quanta arquivos temos
*/
//Abre o diretorio para preparar para listagem
    if ((dir = opendir("C:/db_NoSQL/produtos/")) == NULL)
    perror("opendir() error");
    int li=0,tecla;
    puts("      Produtos cadastrados");
        do
        {
            while ((entry = readdir(dir)) != NULL)
/*
    declara a variavel entry para receber o readddir de do dir e se for difrente de NULL
    ou seja, enquanto arquivo existir (for diferente de nulo) faça
*/
            if ( strcmp( entry->d_name, "." ) && strcmp( entry->d_name, ".." ))

            {

                printf("    %zu) - %s\n", count + 0, indexar[count] = entry->d_name);
              //Alterei. Acredito que o problema esteja aqui, ele está gravando apenas o ultimo nome de arquivo
              //Tentei criar um For aqui, mas mesmo assim, me retorna o ultimo nome em todas as posições.
                count++;

            }
            gotoxy(0,li);
            printf("->");
            gotoxy(79,24);
                tecla=0;
                if(kbhit())
                {
                    tecla = getch();
                    gotoxy(0,li);
                    printf("  ");
                    if(tecla==224)
                        tecla = getch();
                    if(tecla == 72)
                        li--;
                    else
                        if(tecla == 80)
                            li++;
                    if(li > count)
//se a linha que estamos percorrendo for maior que count ele volta para linha 0
                        li=0;
                    else
                        if(li < 1)
//se a linha que estamos percorrendo for menor que 1 ele pula para posição total
                            li=count;
                    gotoxy(0,li);
                    printf("->");
                    gotoxy(79,24);/* se não quiser que cursor fique piscando ali */
                    }

                        }while (tecla != 13);
//Quando tecla for igual a ENTER
system("cls");

for(j = 1; j < 12; j++){//Alterei
printf("%s\n",indexar[j]);
}

//Imprime a linha selecionada, futuramente será usada como index
system("PAUSE");
//Pausa o sistema para podermos visualizar a variavel li
//Essa parte será excluido posteriormente, é apenas para verificação do Index.

                        /*switch(li)
/*
Após a tecla ENTER ser presionada ele pega o numero armazenado em li e troca para caso
correspondente.
*/
                        //{
/*
Agora precisamos fazer com que pelo index pegue o nome do produto(arquivo)
Swtich apenas aceita constant ou seja apenas numeros 1,2,3 etc..
tirar o switch por if talvez.
*/
                           // case 1:
                       // puts(indexar[3]);
                        //}//while(tecla != 27);
}


int main(){

Ele me retorna assim:

img.PNG.f8a0ab1282e27cb2bb6ac42e86557c22.PNG

Ele imprime o ultimo arquivo em ordem alfabética, se eu cadastrar com outro nome antes de Z ele ainda irá pegar "zabcd.txt"

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

#include <iostream>
#include <stdio.h>
#include <locale.h>
#include <conio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <fstream>
#include <string>
#include <dirent.h>
#include <winsock2.h>


using namespace std;

void gotoxy(int x,int y)
{

    COORD c;//Struct COORD recebe c
    c.X = x;//Coluna
    c.Y = y;//Linha
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}


int main()
{
system("MODE con cols=168 lines=60");
DIR *dir;
struct dirent *entry;

size_t count = 0;
char *indexar[100] = {"foo"};
int j = 0;

    if ((dir = opendir("C:/db_NoSQL/produtos/")) == NULL)
    perror("opendir() error");
    int li=0,tecla;
    puts("      Produtos cadastrados");
        do
        {
            while ((entry = readdir(dir)) != NULL)
            if ( strcmp( entry->d_name, "." ) && strcmp( entry->d_name, ".." ))

            {

                printf("    %zu) - %s\n", count + 0, indexar[count] = entry->d_name);
                count++;

            }
            gotoxy(0,li);
            printf("->");
            gotoxy(79,24);
                tecla=0;
                if(kbhit())
                {
                    tecla = getch();
                    gotoxy(0,li);
                    printf("  ");
                    if(tecla==224)
                        tecla = getch();
                    if(tecla == 72)
                        li--;
                    else
                        if(tecla == 80)
                            li++;
                    if(li > count)

                        li=0;
                    else
                        if(li < 1)

                            li=count;
                    gotoxy(0,li);
                    printf("->");
                    gotoxy(79,24);
                    }

                        }while (tecla != 13);

system("cls");

for(j = 1; j < 12; j++){
printf("%s\n",indexar[j]);
}

system("PAUSE");


                        return 0;
}

Obrigado pela dica, separei ele vou fazer os testes nesse agora.

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

Então, consegui com que ele salve os nomes dos arquivos do diretório em um vetor e depois baseado na linha selecionada ele salve o nome em uma outra string para conseguir assim abrir o arquivo e sobrescrever a quantidade. No caso, segue abaixo o código.

 

#include <iostream>
#include <stdio.h>
#include <locale.h>
#include <conio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <fstream>
#include <string>
#include <dirent.h>
#include <winsock2.h>
#include <vector>//Para poder usar o vetor
using namespace std;

void gotoxy(int x,int y)
{

    COORD c;//Struct COORD recebe c
    c.X = x;//Coluna
    c.Y = y;//Linha
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}


int main()
{
system("MODE con cols=168 lines=60");
DIR *dir;
struct dirent *entry;
//size_t conta = 0;
char *indexar[100] = {"foo"};
std::vector<std::string> files;//declarando vetor
string directory = "C:/db_NoSQL/produtos/";
//char *file;
size_t conta = 0;
//string *arr;
//string name;
int j = 0;
int x = 0;
    if ((dir = opendir("C:/db_NoSQL/produtos/")) == NULL)
    perror("opendir() error");
    int li=1,tecla;
    puts("      Produtos cadastrados");
        do

        {
            while ((entry = readdir(dir)) != NULL)
            {
                if ( strcmp( entry->d_name, "." ) && strcmp( entry->d_name, ".." ))

                {
                        printf("    %zu) - %s\n", conta + 1, entry->d_name);
                        conta++;

                }
            }
            gotoxy(0,li);
            printf("->");
            gotoxy(79,24);
                tecla=0;
                if(kbhit())
                {
                    tecla = getch();
                    gotoxy(0,li);
                    printf("  ");
                    if(tecla==224)
                        tecla = getch();
                    if(tecla == 72)
                        li--;
                    else
                        if(tecla == 80)
                            li++;
                    if(li > conta)

                        li=0;
                    else
                        if(li < 1)

                            li=conta;
                    gotoxy(0,li);
                    printf("->");
                    gotoxy(79,24);
                    }

                        }while (tecla != 13);

system("cls");
int i = 0;//abrindo novamente o local do arquivo para pegar os arquivos 
    if ((dir = opendir("C:/db_NoSQL/produtos/")) != nullptr) {
        while ((entry = readdir(dir)) != nullptr) {
            if ( strcmp( entry->d_name, "." ) && strcmp( entry->d_name, ".." ))
              //usando push para pegar todos os nomes e indexar em files
            files.push_back(std::string (entry->d_name));
        }
        closedir (dir);
    } else {
        perror ("opendir");
        return EXIT_FAILURE;
    }
    string teste;
    string qtd;
    for (int i=0; i < 1; ++i)//imprime a posição do vetor files menos a linha que foi selecionada 
    std::cout << files[li - 1] << ' '<<endl;
    teste = files[li - 1];// passamos posição do vetor -1 para uma string assim pegamos seu valor
    cout<<teste<<endl;
    std::ofstream out(directory + teste);//usamos ele para abrir o arquivo 
    puts("Insira o valor atualizado");
    std::getline(std::cin,qtd);
    out<<qtd;//escreve o valor inserido no txt.


    return EXIT_SUCCESS;

system("PAUSE");


                        return 0;
}

Obrigado pela força, não consegui indexar do uma maneira "normal" apresentava erros, após pesquisar um "pouco" descobri essa biblioteca vector. Próximo passo agora é melhorar o menu com o tópico acima que indicou.

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

12 horas atrás, Ywill disse:

Próximo passo

 

Bom que funcionou!
 

Li o código e eis meu palpite grátis:

  • use o menu como eu mostrei. Teste ao menos. Porque?
    • não precisa fazer nada em relação ao menu
    • a lógica do menu não fica misturada com o código

Sobre o código:

  • escreveu um programa em C. C++ é mais expressiva e mais simples como linguagem pra montar essas coisas
  • conio.h é dos anos 80. Difícil imaginar que se precise disso no século XXI. E eu mostrei que não precisa
  • C++ tem map que pode usar ao invés de vector. Usando map pode pegar a lista de arquivos em ordem alfabética sem ter que fazer nada
  • Seria bem conveniente ter '.' E '..' para poder navegar pelas pastas.
  • O programa tem muitos números mágicos com os códigos de teclas. Não deve usar essas coisas. O sistema já tem omes para TODAS as teclas por exemplo.
  • gotoxy() deveria gotoyx() e mostrar linha e coluna. É mais prático que a notação cartesiana.
  • não misture lógica com a apresentação. Isso é um desastre em termos de manutenção e teste
  • nào tem muito sentido user exit() em main(). return em mai é a mesma coisa que exit
  • use funções.
  • use C++. C++ tem uma classe filesystem muito mais prática que dirent
12 horas atrás, Ywill disse:

essa biblioteca vecto

 

vector é uma classe e não uma biblioteca.

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

Em 24/07/2022 às 00:22, Ywill disse:

não consegui indexar do uma maneira "normal" apresentava erros

 

Que seria "indexar de uma maneira normal"?  Pensou em dizer que erros eram esses? Postar o código com erro?

 

talvez fosse mais simples e portavel usar um arquivo csv para conter os produtos. SQLite importa o arquivo em um passo só...

Em 14/07/2022 às 18:14, Ywill disse:

a leitura de uma linha já escrita no CMD

 

Não entendo o que significa. E o título do post também podia ser mais expressivo assim outros que se interessassem poderiam acessar. Algo como "navegar com as setas do teclado pela lista de arquivos de uma pasta"  não seria mais perto do que tenta fazer?

Link para o comentário
Compartilhar em outros sites

MongoDB por exemplo aceitaria 

 

mongoimport --type csv --headerline --drop -d testando -c products "C:/db_NoSQL/produtos/produtos.csv

 

e importaria todos os produtos de uma vez

 

Google Cloud aceitaria algo como

 

LOAD DATA INFILE ... CHARACTER SET 'utf8mb4'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' ESCAPED BY '\\'.

 

 

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!