Ir para conteúdo
Fórum Script Brasil
  • 0

Copiar posições da string para inteiro


princknoby

Pergunta

Olá a todos, acho que vou poluir esse fórum de tantos pedidos de ajuda kkkkkkkk

Estou fazendo o seguinte exercício de strings: Leia uma cadeia de caracteres no formato “DD/MM/AAAA” e copie o dia, mês e ano
para 3 variáveis inteiras. Antes disso, verifique se as barras estão no lugar certo, e se DD,
MM, e AAAA são numéricos. Caso algum deles não seja, ou alguma barra estiver fora do
lugar ou faltando, informe para o usuário qual foi o erro e peça para repetir a operação.
Faça isso até que ele forneça os dados corretamente.

 

Consegui fazer, ficou extremamente grande, mas consegui kkkk Estou com apenas um problema... "...Copie dia, mes e ano para 3 variáveis inteiras)
Fui pesquisar e descobri a função atoi do cabeçalho <stdlib.h>
Porém eu preciso copiar as posições específicas da string, para os inteiros. Eu tentei fazer da seguinte forma:

	    //converter dia tipo 'string' para dia tipo 'int'
    for (i = 0; i < 2; i++) /*dia está em [0] e [1], então devemos percorrer apenas essas posições*/ {
        dia=atoi(data);
    }
	    //receber mes
    for (i = 3; i < 5; i++) { /*mes esta nas posições [3] e [4] */
        mes=atoi(data);
    }
	    //receber ano
    for (i = 6; i < 10; i++) /*ano esta em [6][7][8][9]*/ {
        ano=atoi(data);
    }

 

Porém dessa forma, todas as saídas (dia, ano e mes) estão recebendo o mesmo valor! Estão recebendo todas, o valor da posição [0] e [1].
E quando tento fazer como arrays:

ano[i]=atoi(data[i]) 

da erro, e o compilador me da alguns avisos sobre ponteiros, mas eu ainda não aprendi ponteiros.

OBS: não postei o código todo, porque está muito grande, mas caso seja necessário, só pedir que eu mando.

Editado por princknoby
Link para o comentário
Compartilhar em outros sites

3 respostass a esta questão

Posts Recomendados

  • 0

@princknoby  Vou deixar um código pronto lá embaixo, mas se quiser q a gente julgue o seu, coloque ele aqui q a gente confere os enganos

Só uma dica: q eu acho valiosa, como você está começando, procura usar as funções prontas somente quando for algo muito cabeludo pra fazer na unha. Tente fazer as suas próprias funções sempre que possível.

Outra dica: Essa talvez você queira ignorar e deva se achar que não ta certo, quando você for fazer exercícios para aprender, exercícios que você não precisa entregar nem mostrar pra ninguém, procure evitar fazer esses exercícios que peçam essas bobei rinhas de verificar entrada de usuário, eles não desafiam o seu intelecto, só são cansativos e chatos de serem feitos, claro quando é um professor que está pedindo, você faz e entrega pra ele mas quando está resolvendo na sua casa, PULE, ninguém aprende C verificando se o ursoario digitou "batata" quando você pediu a IDADE dele, uma regra legal q um professor me passava era "Suponha que a entrada sempre esteja correta", dessa forma você só se preocupa com o algoritmo, que é o que interessa

1- Apesar de estar em um loop, você não faz nenhuma relação entre o contador e algo dentro do código. O cabeçalho do atoi é:

int atoi(const char *str)

O que significa q ela recebe uma string e devolve um inteiro, supondo q data é a string que contem a data completa -> "12/02/1992", o que você esta fazendo é converter toda data duas vezes para a variavel dia, perceba q você esta tentando converter tdo, com barras e 8 algarismos.

4 horas atrás, princknoby disse:

for (i = 0; i < 2; i++) /*dia está em [0] e [1], então devemos percorrer apenas essas posições*/ {         dia=atoi(data);     }

Resposta:

Provavelmente tem erros, mas a ideia ta aew, espero ter ajudado, abracos e bons estudos

/*Leia uma cadeia de caracteres no formato “DD/MM/AAAA” e copie o dia, mês e ano
para 3 variáveis inteiras. Antes disso, verifique se as barras estão no lugar certo, e se DD,
MM, e AAAA são numéricos. Caso algum deles não seja, ou alguma barra estiver fora do
lugar ou faltando, informe para o usuário qual foi o erro e peça para repetir a operação.
Faça isso até que ele forneça os dados corretamente.
*/

#include <stdio.h>
#include <stdlib.h>

enum Erros
{
	BARRAS_ERRADAS = 2,
	NUMEROS_ERRADOS,
	PALAVRA_MAIOR
};

//Comecamos criando 2 funcoes de suporte para solucionar
//nosso exercicio

//// ACHEI que a gente fosse usar o atoi, mas acabou que não usamos, de qualquer maneira
//// a dica de você criar suas proprias funcoes ainda é valida, então vou deixar o MyAtoi
//// para você dar uma olhada
// Conversor de string para numero
int MyAtoi (const char *a)
{
	int i;
	int result = 0;
	
	// Você não precisa intender isso, mas seria legal
	// se o fizesse, não é muito complicado e é uma 
	// solucao q eu acho bem sutil
	for (i = 0; a[i]; i++)
		result = result * 10 + (a[i] - '0');
	
	return result;
}


//Valida a entrada do usuario
//RETORNOS:
// 1 -> A palavra esta no formato NN\\NN\\NNNN
// 2 -> A barra esta no lugar errado
// 3 -> Algum dos numeros foram colocados de maneiro erronia
// 4 -> Foram digitados mais numeros do que o nescessario
char VerificaEntrada (const char *data)
{
	int i = 0;
	
	char limSup = 0;
	
	for (i = 0; data[i]; i++)
	{
		// As barras precisam estar nas posicoes 2 e 5 da string
		if (i == 2 || i == 5)
		{
			if (data[i] != '\\' && data[i] != '/')
				return 2; // ta errado
		}
		else //todo o resto tem q ser um digito de 0 a 9
		{
			switch (i)
			{
				//Dezena do dia
				case 0:
					limSup = '3';
				break;
				
				//Unidade do dia
				case 1:
					if (data[i-1] >= '0' && data[i-1] < '3')
						limSup = '9';
					else
						limSup = '1';
				break;
				
				//Dezena do mes
				case 3:
					limSup = '1';
				break;
				
				//Unidade do mes
				case 4:
					if (data[i-1] == '0')
						limSup = '9';
					else
						limSup = '2';
				break;
				
				//Milhar do ano
				case 6:
					limSup = '2';
				break;
				
				//Centena do ano
				case 7:
					if (data[i-1] < '2')
						limSup = '9';
					else
						limSup = '0';
				break;
				
				//Dezena do ano
				case 8:
					if (data[i-2] < '2')
						limSup = '9';
					else
						limSup = '1';
				break;
				
				// Unidade do ano
				case 9:
					if (data[i-3] < '2')
						limSup = '9';
					else
						limSup = '8';
				break;
			}
			
			if (data[i] < '0' || data[i] > limSup)
				return 3;
		}
	}
	
	//Caso a palavra seja maior do que deveria ser
	if (i != 10)
		return 4;
	
	return 1;
} 

int main ()
{
	//Armazena a data que sera entrada
	char data[20];
	int i = 0;
	
	int tmp = 0;
	
	while (1)
	{
		printf ("DD\\MM\\AAAA\n");
		scanf ("%s", data);
		
		if ((tmp = VerificaEntrada (data)) == 1)
			break;
		
		switch (tmp)
		{
			case BARRAS_ERRADAS:
				printf ("Erro na barra\n");
			break;
			
			case NUMEROS_ERRADOS:
				printf ("Algum numero ta errado\n");
			break;
			
			case PALAVRA_MAIOR:
				printf ("A palavra esta maior do que era nescessario\n");
			break;
		}
	}

    return (0);
}

 

Edit:

-----------------------------------------------------------------------------------

Aqui uma maneira de fazer seguindo o raciocinio que você propos

int main ()
{
	//Armazena a data que sera entrada
	char data[20];
	int i = 0;
	
	int dia, mes, ano;
	
	int tmp = 0;
	
	while (1)
	{
		printf ("DD\\MM\\AAAA\n");
		scanf ("%s", data);
		
		//Coloca \0 nas posicoes esperada de forma manual
		data[2] = '\0';
		data[5] = '\0';
		
		// Onde fica a primeira barra
		dia = MyAtoi (data);
		mes = MyAtoi (&data[3]);
		ano = MyAtoi (&data[6]);
		
		printf ("%d\t%d\t%d\n", dia, mes, ano);
	}

    return (0);
}

 

Editado por Nefisto
Link para o comentário
Compartilhar em outros sites

  • 0

Obrigado @Nefisto ajudou bastante, confesso que fiquei um pouco perdido no seu primeiro código, vou salvar ele aqui, e dar uma estudada nele rsrs, a respeito de criar a função atoi, mesmo com seu exemplo não faço ideia de como fazer isso. 
Baixei uma apostila de C: http://www2.dcc.ufmg.br/disciplinas/pc/source/introducao_c_renatocm_deeufmg.pdf e percebi que não estou tão bom assim em coisas básicas, percebi isso, após ver alguns exemplos na apostila, que eu deveria saber, de coisas básicas, e que eu não estava sabendo, a apostila está me acrescentando muitas coisas que eu não sabia. Vou continuar estudando ela, e estudando esse seu códio.

 

Esse seu último código me ajudou bastante, estava faltando um '&' no meu código, ai declarei os inteiros como arrays, e deu certo.
Só uma coisa que me deixou encabulado rsrs 

Eu fiz da seguinte forma: 

	//converter dia tipo 'string' para dia tipo 'int'
	for (i = 0; i < 2; i++) /*dia está em [0] e [1], então devemos percorrer apenas essas posições*/ {
		dia[i]=atoi(&data[i]);
	}

	//receber mes
	for (i = 3; i < 5; i++) { /*mes esta nas posições [3] e [4] */ 
		mes[i]=atoi(&data[i]);
	}

	//receber ano
	for (i = 6; i < 10; i++) /*ano esta em [6][7][8][9]*/ {
		ano[i]=atoi(&data[i]);
	}

Ao fazer esse código, eu imaginei que em cada posição das variáveis, como ex: O array 'dia' a cada laço, ele iria armazenar na posição do array, o que tava na posição da string. Foi isso que pensei inicialmente... Mas quando fui imprimir as saídas, tentei imprimir o vetor inteiro, usando '%ls' porém apareceu foi outras coisas, ai pensei "hmmm... achou que vou ter que imprimir posição por posição" 

Tá, fiz: printf ("%d%d", dia[0], dia[1]); 

Mas pra mim surpresa, em cada posição de dia, já estava o dia todo: Ex dia era 23 >> imaginei que o '2' estaria em [0] e o 3 em [1], mas não, em dia[0], já tava o número 23 todo... 

Então acabou que quando fiz: printf ("%d", dia[0]); eu imprimi o dia todo, os dois caracteres...
Isso me deixou confuso, já que quando eu estudava vetores, cada número ficava em uma posição, e até quando imprimo uma string caracter por caracter, cada caracter está em uma posição... 

Meu código tá bem poluído em comparação ao seu, mas deixarei aqui. 
Muito obrigado 😄

"

21 horas atrás, Nefisto disse:

ninguém aprende C verificando se o ursoario digitou "batata" quando você pediu a IDADE dele

Ri demais aqui kkkkkkkkkkkkkkkkkkkkkkkkkkkk você está corretissimo, concordo com você, mas eu fico literalmente louco, quando aparece algum exercício, mesmo que seja desse tipo, e eu não consigo fazer... Ai eu acabo fazendo kkkkkk 

 

21 horas atrás, Nefisto disse:

int MyAtoi (const char *a) { int i; int result = 0; // Você não precisa intender isso, mas seria legal // se o fizesse, não é muito complicado e é uma // solucao q eu acho bem sutil for (i = 0; a[i]; i++) result = result * 10 + (a[i] - '0'); return result; } 

Eu realmente tetei entender essa função, mas ainda não consegui. 
E olhando pro restante do seu código, percebi que eu poderia ter feito algumas coisas diferentes no meu, que deixariam ele mais "enxuto". 
Mas deixo aqui o meu código gigantesco rsrs: 

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
	void limpar () {
    int ch;
    while ((ch=fgetc(stdin)) != '\n' && ch != EOF);
} /*você me passou outra função pra limpar o buffer, eu deixei essa um pouco mais parecida com a sua*/
  /*ela continua não sendo recomendada?*/ 
  /*essa questão de limpar o buffer, é outra coisa que buga minha mente rsrs*/
	void pausar () {
    printf ("\nPress [ENTER] to quit...");
    scanf ("%*c");
}
	int main () {
    char data[100];
    int dia[10], mes[10], ano[10], i, cont=0, TAM=1;
	    printf ("Digite a data: ");
    scanf ("%99[^\n]", data);
    limpar ();
	    //vamos analisar se as datas são numeros
    for (i = 0; i < TAM; i++) {/*vamos repetir esse laço sempre que entrar em algum lugar!*/
        while (data[0] < 48 || data[0] > 57) {
            printf ("\nAtual data digitada: %s \n", data);
            printf ("\nO valor que voce digitou referente ao dia não é numérico!\n");
            printf ("Por favor , digite a data toda (DD/MM/AAAA novamente: ");
            scanf ("%99[^\n]", data);
            limpar ();
            cont++;
        }
        while (data[1] > 57 || data[1] < 48) {
            printf ("\nAtual data digitada: %s \n", data);
            printf ("\nO valor que voce digitou referente ao dia não é numérico!\n");
            printf ("Por favor , digite a data toda (DD/MM/AAAA novamente: ");
            scanf ("%99[^\n]", data);
            limpar ();
            cont++;
        }
	        if (cont != 0) {//significa que ele leu algo errado, e vamos checar de novo por via de duvidas
                    TAM++;
                    cont=0;
                }
        else
            break;
    }
    //--------------------------------------------------------------------------
    
    //mes
    for (i = 0; i < TAM; i++) {/*vamos repetir esse laço sempre que entrar em algum lugar!*/
        while (data[3] < 48 || data[3] > 57) {
            printf ("\nAtual data digitada: %s \n", data);
            printf ("\nO valor que voce digitou referente ao mes não é numérico!\n");
            printf ("Por favor , digite a data toda (DD/MM/AAAA novamente: ");
            scanf ("%99[^\n]", data);
            limpar ();
            cont++;
        }
        while (data[4] > 57 || data[4] < 48) {
            printf ("\nAtual data digitada: %s \n", data);
            printf ("\nO valor que voce digitou referente ao mes não é numérico!\n");
            printf ("Por favor , digite a data toda (DD/MM/AAAA novamente: ");
            scanf ("%99[^\n]", data);
            limpar ();
            cont++;
        }
        if (cont != 0) {//significa que ele leu algo errado, e vamos checar de novo por via de duvidas
                    TAM++;
                    cont=0;
                }
        else
            break;
    }
    //--------------------------------------------------------------------------
	    //ano
    for (i = 0; i < TAM; i++) {/*vamos repetir esse laço sempre que entrar em algum lugar!*/
        while (data[6] < 48 || data[6] > 57)  {
            printf ("\nAtual data digitada: %s \n", data);
            printf ("\nO valor que voce digitou referente ao ano não é numérico!\n");
            printf ("Por favor , digite a data toda (DD/MM/AAAA novamente: ");
            scanf ("%99[^\n]", data);
            limpar ();
            cont++;
        }
        while (data[7] > 57 || data[7] < 48)  {
            printf ("\nAtual data digitada: %s \n", data);
            printf ("\nO valor que voce digitou referente ao ano não é numérico!\n");
            printf ("Por favor , digite a data toda (DD/MM/AAAA novamente: ");
            scanf ("%99[^\n]", data);
            limpar ();
            cont++;
        }
        while (data[8] > 57 || data[8] < 48)  {
            printf ("\nAtual data digitada: %s \n", data);
            printf ("\nO valor que voce digitou referente ao ano não é numérico!\n");
            printf ("Por favor , digite a data toda (DD/MM/AAAA novamente: ");
            scanf ("%99[^\n]", data);
            limpar ();
            cont++;
        }
        while (data[9] > 57 || data[9] < 48)  {
            printf ("\nAtual data digitada: %s \n", data);
            printf ("\nO valor que voce digitou referente ao ano não é numérico!\n");
            printf ("Por favor , digite a data toda (DD/MM/AAAA novamente: ");
            scanf ("%99[^\n]", data);
            limpar ();
            cont++;
        }
        if (cont != 0) {//significa que ele leu algo errado, e vamos checar de novo por via de duvidas
                        TAM++;
                        cont=0;
                    }
            else
                break;
        }
    //--------------------------------------------------------------------------
    
    //vamos verificar as posições das barras
    //devem ter barras nas posições [2] e [5]
    for (i = 0; i < TAM; i++) {/*vamos repetir esse laço sempre que entrar em algum lugar!*/
    while (data[2] != '/') {
        printf ("\nAtual data digitada: %s \n", data);
        printf ("\nOnde voce digitou '%c' deve ser barra!", data[2]);
        printf ("Por favor, digite a data INTEIRA novamente no formato DD/MM/AAAA: ");
        scanf ("%99[^\n]", data);
        limpar ();
        cont++;
    }
    while (data[5] != '/') {
        printf ("\nAtual data digitada: %s \n", data);
        printf ("\nOnde voce digitou '%c' deve ser barra!", data[5]);
        printf ("Por favor, digite a data INTEIRA novamente no formato DD/MM/AAAA: ");
        scanf ("%99[^\n]", data);
        limpar ();
        cont++;
    }
    if (cont != 0) {//significa que ele leu algo errado, e vamos checar de novo por via de duvidas
                        TAM++;
                        cont=0;
                    }
            else
                break;
        }
	    //converter dia tipo 'string' para dia tipo 'int'
    for (i = 0; i < 2; i++) /*dia está em [0] e [1], então devemos percorrer apenas essas posições*/ {
        dia[i]=atoi(&data[i]);
    }
	    //receber mes
    for (i = 3; i < 5; i++) { /*mes esta nas posições [3] e [4] */ 
        mes[i]=atoi(&data[i]);
    }
	    //receber ano
    for (i = 6; i < 10; i++) /*ano esta em [6][7][8][9]*/ {
        ano[i]=atoi(&data[i]);
    }
	    //até que enfim chegamos ao final do programa!
    //vamos imprimir a data: DD/MM/AAAA
	    printf ("\nDIA:%d", dia[0]);
    printf ("\nBARRA:%c", data[2]);
    printf ("\nMES:%d", mes[3]);
    printf ("\nBARRA:%c", data[5]);
    printf ("\nANO:%d\n", ano[6]);
	    pausar ();
    return 0;
}
	

 

 

Obrigado mais uma vez @Nefisto

Editado por princknoby
Link para o comentário
Compartilhar em outros sites

  • 0
40 minutos atrás, princknoby disse:

void limpar () {     int ch;     while ((ch=fgetc(stdin)) != '\n' && ch != EOF); }

Agora ta certinho 😜

 

Pega o habito de conferir o retorno da funcao, o atoi retorna um int e não um vetor de int, o vetor é desnecessario (como você mesmo percebeu)

41 minutos atrás, princknoby disse:

int dia[10], mes[10], ano[10]

 

Dica: Uma boa maxima quando se esta programando é -> "Se você digitar  mesmo codigo mais do que 2 vezes, pare e volte, a chance de estar errado é muito grande"

Ota: Encontre um bom balanco entre "readability vs efficiency", não sei como traduz pro portugues, seria legivel? enfim, você esta verificando se a data esta no range de 48 a 57, que são as letras 0 e 9, só q a não ser q você se lembre da tabela ASCII você não vai lembrar o que isso faz daki um mes, e qualquer outra pessoa q for ler vai achar q isso é gambiarra:

46 minutos atrás, princknoby disse:

(data[9] > 57 || data[9] < 48)

Deixe as coisas legiveis, para o seu proprio bem

(data[9] > '9' || data[9] < '0')

Acho q de grosso é isso, com o tempo o seu codigo vai enxugando, afinal, o melhor agoritmo é aquele que você sabe fazer =D 

Abracos

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,5k
×
×
  • Criar Novo...