Ir ao conteúdo
  • Cadastre-se

Pedrohtico

Membro Júnior
  • Posts

    15
  • Cadastrado em

  • Última visita

Reputação

8
  1. Deu certo. Na verdade eu só mudei essa parte: for(i = 0; i < *altura; i++){ for(j = 0; j < *largura; j++){ fscanf(imagem, "%d", &pixel[(*altura)*i + j]->r); fscanf(imagem, "%d", &pixel[(*altura)*i + j]->g); fscanf(imagem, "%d", &pixel[(*altura)*i + j]->b); printf("PIXEL 1: R: %d G: %d B: %d (%d) (%d)\n", pixel[(*altura)*i + j]->r, pixel[(*altura)*i + j]->g, pixel[(*altura)*i + j]->b, i, j); } } para isso: for(i = 0; i < *altura; i++){ for(j = 0; j < *largura; j++){ fscanf(imagem, "%d", &(*pixel)[(*altura)*i + j].r); fscanf(imagem, "%d", &(*pixel)[(*altura)*i + j].g); fscanf(imagem, "%d", &(*pixel)[(*altura)*i + j].b); printf("PIXEL 1: R: %d G: %d B: %d (%d) (%d)\n", (*pixel)[(*altura)*i + j].r, (*pixel)[(*altura)*i + j].g, (*pixel)[(*altura)*i + j].b, i, j); } } E o printf eu mudei do mesmo jeito: De: pixel[(*altura)*i + j]->r Para: (*pixel)[(*altura)*i + j].r E deu certo dessa forma. Antes eu usei o debug e estava dando "Segmentation Fault". Mas pra mim essas 2 formas são equivalentes, não sei o porque da primeira dar erro e a segunda não. De qualquer forma, muito obrigado pela ajuda.
  2. Então vangodp, ajudou bastante e acho que entendi, mas não está dando certo na prática: Eu mudei para um vetor, como você mostrou ser mais prático (e realmente vai ser, em outras funções que vou utilizar no programa) e, pela lógica, quando eu passasse para a função, a função deveria receber um **pixel, já que foi criado um *pixel. Ficou dessa forma: void ler_imagem(matriz_pixel **pixel, int *largura, int *altura, int *max, char *code, char *argv[]){ // Lê os primeiros valores do arquivo PPM int i, j; FILE *imagem; char nome[101]; scanf("%s", nome); imagem = fopen(nome, "r"); // Abre o arquivo da imagem PPM if(imagem == NULL){ printf("Erro na abertura do arquivo!\n"); exit(1); } fscanf(imagem, "%s", code); fscanf(imagem, "%d", largura); fscanf(imagem, "%d", altura); fscanf(imagem, "%d", max); *pixel = (matriz_pixel*) malloc((*largura)*(*altura)*sizeof(matriz_pixel)); if(*pixel == NULL){ printf("Erro de memoria!\n"); exit(1); } printf("PIXEL 1: R: %d G: %d B: %d\n", pixel[0]->r, pixel[0]->g, pixel[0]->b); for(i = 0; i < *altura; i++){ for(j = 0; j < *largura; j++){ fscanf(imagem, "%d", &pixel[(*altura)*i + j]->r); fscanf(imagem, "%d", &pixel[(*altura)*i + j]->g); fscanf(imagem, "%d", &pixel[(*altura)*i + j]->b); printf("PIXEL 1: R: %d G: %d B: %d (%d) (%d)\n", pixel[(*altura)*i + j]->r, pixel[(*altura)*i + j]->g, pixel[(*altura)*i + j]->b, i, j); } } printf("PIXEL 1: R: %d G: %d B: %d\n", pixel[0]->r, pixel[0]->g, pixel[0]->b); fclose(imagem); } int main(int argc, char *argv[]){ int i, j; // Variáveis auxiliares matriz_pixel *pixel; int max, largura, altura; // Variáveis dos atributos da imagem PPM char code[3]; ler_imagem(&pixel, &largura, &altura, &max, code, argv); escrever_variaveis(&pixel, largura, altura, max, code); free(pixel); return 0; } O que acontece agora é que ele não está lendo os valores do arquivo e guardando nas variáveis. Na verdade, quando executa, ele lê os três primeiros valores, ou seja, o primeiro pixel, sendo os valores R, G, B, e guarda na primeira posição do vetor, que contém a struct matriz_pixel. E logo depois ele para de funcionar. Então eu creio que é algum problema com a alocação talvez, já que ele guarda os valores apenas na posição 0 do vetor e não nas outras. P.S.: Quando você falou que para manipular o vetor, teria que ser [i*j], acredito eu que teria que ser [10*i + j]. Pois apenas multiplicando o valor de i*j, você teria um problema na linha e na coluna 0, onde todos os valores dariam na posição 0 do vetor. Edit 1: Eu testei guardando apenas na posição 0 do vetor e realmente está funcionando desse jeito, ou seja, os valores não estão sendo guardados apenas dentro da função, mas posso usá-los em outras funções também. O problema é que ele está alocando apenas a posição 0 do vetor e não as demais.
  3. Aqui tem 5 imagens PPM, pode tentar com qualquer uma delas. Na segunda, ela dá erro de memória, ou seja, já tem algum problema com a alocação. Na primeira, terceira, quarta e quinta imagem, dá esse problema descrito anteriormente. Imagens_PPM.rar
  4. Olá, eu estou fazendo um programa que lê imagens PPM, mas estou tendo um problema. A seguinte função lê a imagem e guarda dentro de variáveis criadas na main. O problema está no ponteiro de ponteiro, ou seja, a matriz "pixel": typedef struct{ int r, g, b; }matriz_pixel; void ler_imagem(matriz_pixel **pixel, int *largura, int *altura, int *max, char *code, char *argv[]){ // Lê os primeiros valores do arquivo PPM int i, j; FILE *imagem; char nome[101]; scanf("%s", nome); imagem = fopen(nome, "r"); // Abre o arquivo da imagem PPm if(imagem == NULL){ printf("Erro na abertura do arquivo!\n"); exit(1); } fscanf(imagem, "%s", code); fscanf(imagem, "%d", largura); fscanf(imagem, "%d", altura); fscanf(imagem, "%d", max); pixel = (matriz_pixel**) malloc (*altura * sizeof(matriz_pixel*)); // Aloca a matriz de struct que guardará os valores RGB if(pixel == NULL){ printf("Erro de memoria!\n"); exit(1); } for(i = 0; i < *altura; i++){ pixel[i] = (matriz_pixel*) malloc (*largura * sizeof(matriz_pixel)); if(pixel[i] == NULL){ printf("Erro de memoria!\n"); exit(1); } } printf("PIXEL 1: R: %d G: %d B: %d\n", pixel[0][0].r, pixel[0][0].g, pixel[0][0].b); for(i = 0; i < *altura; i++){ for(j = 0; j < *largura; j++){ fscanf(imagem, "%d", &pixel[i][j].r); fscanf(imagem, "%d", &pixel[i][j].g); fscanf(imagem, "%d", &pixel[i][j].b); } } printf("PIXEL 1: R: %d G: %d B: %d\n", pixel[0][0].r, pixel[0][0].g, pixel[0][0].b); fclose(imagem); } Essa segunda função eu fiz apenas para saber se os valores estavam sendo guardados corretamente: void escrever_variaveis(matriz_pixel **pixel, int largura, int altura, int max, char *code){ printf("Code: %s\n", code); printf("Largura: %d\n", largura); printf("Altura: %d\n", altura); printf("Tonalidade max: %d\n", max); printf("PIXEL 1: R: %d G: %d B: %d\n", pixel[0][0].r, pixel[0][0].g, pixel[0][0].b); } E então, tem a função main(), que apenas inicializa as variáveis e chama as duas funções anteriores: int main(int argc, char *argv[]){ int i, j; matriz_pixel **pixel; // Variáveis dos atributos da imagem PPM int max, largura, altura; char code[3]; ler_imagem(pixel, &largura, &altura, &max, code, argv); escrever_variaveis(pixel, largura, altura, max, code); free(pixel); for(i = 0; i < altura; i++){ free(pixel[i]); } return 0; } Eu coloquei um printf para mostrar o valor RGB guardado dentro do primeiro pixel da matrix de struct "pixel". Esse printf foi colocado 3 vezes. A primeira vez ela printa o lixo logo depois de alocar a matriz pixel. Na segunda o valor após ler a imagem PPM. E a terceira, que fica na segunda função, deveria mostrar os mesmos valores que a segunda vez. Entretanto, o cmd dá mal funcionamento nesse printf e encerra o programa. Eu imagino que seja algum problema com a alocação dentro da função, como por exemplo se ela desalocasse quando acabasse a função, pois os valores são printados na segunda vez de forma correta. Apenas a terceira vez dá problema. Agradeço a ajuda desde já. Edit 1: Ao retirar o terceiro printf, a variável (matriz_pixel **pixel) no nome da função e (pixel) na chamada dela, ela contina dando esse erro. Então eu descobri que tanto esse terceiro printf quanto o free(pixel) no final do main estão dando esse erro (se eu retirar essas duas partes, o programa funciona normalmente), o que me faz acreditar que é justamente algum problema com a alocação da matriz "pixel" dentro da função "ler_imagem". Edit 2: Se eu inicializo a variável "matriz_pixel pixel**" globalmente, o programa para de dar erro e funciona normalmente.
  5. Isrnick, muito bom. Eu acho que eu nunca imaginaria isso como o problema, então obrigado haha. E vangodp, valeu também pela explicação, agora entendi melhor. Obrigado pelos dois pela ajuda
  6. Acabei de fazer um programa igual ao seu. Tentei já inicializando o vetor de inteiros com 10 e 30 e depois tentei pedindo o valor ao usuário. Em ambos os casos o resultado foi 11 e 35, e eu não faço ideia o porquê haha.
  7. Deu certo dessa forma. Mas não entendi muito bem o porquê. Quando não se especifica os tipos, o compilador meio que modifica um pouco os valores para realizar operações de tipos diferentes?
  8. Dentro de um programa que eu fiz, tem um detalhe que está me incomodando. Existe um vetor de inteiros que em determinado momento eu preciso multiplicar um de seus valores por 1.2. Quando eu faço isso dessa forma, quando o valor do vetor é 10, por exemplo: ataque1[i] = 1.2*ataque1[i]; O resultado sempre sai 1 abaixo do esperado. No caso, a multiplicação de 1.2*10 dá 11 como resultado. Quando eu faço com 30, dá 35 ao invés de 36, etc. Quando eu faço da seguinte forma: ataque1[i] = 12*ataque1[i]/10; O resultado dá certo. 12, quando ataque1 é 10, por exemplo. Eu imagino que seja algum problema por estar multiplicando um float (1.2) por uma variável do tipo inteiro. Se alguém puder me ajudar, eu agradeceria.
  9. Então devair1010, esse pensamento também funciona, porém é necessário uma mudança. Desse jeito que você mostrou, só funcionaria se o último número estivesse entre 10 e 150. Se ele não estivesse, ele não seria printado na tela e o espaço do penúltimo número continuaria lá. Assim, você teria que fazer um programa gigante tentando sempre achar o último valor que está entre o intervalo escolhido, que no caso é 10 e 150. Não adiantaria apenas conferir se o último número está ou não no intervalo. Imagine que o oitavo, nono e décimo número não estão entre o intervalo 10 e 150. Então seria necessário tirar o espaço depois do sétimo número, assim como se só o primeiro estivesse no intervalo, você precisaria conferir se os 9 últimos estão no intervalo para poder retirar o espaço. Para fazer essas condições, seria um programa muito grande com várias condições e isso porque são apenas 10 números inseridos, imagine com 100 ou até 1000, que precisariam de, no pior dos casos, 99 e 999 verificações de condição, respectivamente. Por isso o método apresentado acima é mais prático, pois funciona de qualquer maneira, enquanto esse seria um programa muito confuso e exagerado.
  10. Existem dois erros no seu algoritmo: 1 - Você utiliza o comando "escolha", mas no fim utiliza o comando "fimenquanto" para terminá-lo, enquanto o certo seria utilizar o comando "fimescolha". 2 - Antes de começar o comando "escolha", você escreve: n<-randi(6) escreval (randi(6)) Dessa forma, você vai fazer a variável "n" receber um valor inteiro de 0 a 6 e logo depois você irá randomizar novamente outro número de 0 a 6 e escrevê-lo. Portanto para que ele escreva o número contido na variável, é necessário que você utilize o comando "escreval" para a variável "n" e não para "randi(6)". Assim, o correto seria: n<-randi(6) escreval (n) Espero ter ajudado.
  11. Você apenas esqueceu uma última vírgula entre "E igual a: " e A*b. Portanto, o correto seria: Escreva("O resultado de",a,"X",b,"E igual a: ",A*b) Lembre-se que em concatenação de caracteres e variáveis dentro do comando "escreva" ou "escreval", tudo deve estar separado entre vírgulas. Espero ter ajudado.
  12. Eu achei um jeito de resolver seu problema, mas não ficou muito simples. Assim, vou tentar explicar passo a passo o funcionamento do algoritmo. Saiba que usei funções pré-definidas do visualg como "numpcarac", "copia" e "compr" e se você não as conhecer, pesquise na internet, pois ficaria ainda mais extenso eu explicá-las aqui. Não se assuste com o tamanho da resposta, pois tentei detalhar o máximo e, além disso, não é tão complicado quanto parece. Segue o algoritmo completo: Primeiramente, eu criei uma variável de nome "frase" e tipo "caracter", para que ela comporte a frase que vai aparecer no final do programa, que é justamente a que você quer. Também criei uma variável de nome "aux" e tipo "caracter", que vai ter duas funções no algoritmo, mas a primeira vai ser receber o valor convertido do valor de uma determinada posição x do vetor "num" do tipo inteiro em caracter. Dessa forma, vai ser possível que você adicione esses valores à variável "frase", o que será essencial para retirar essa última vírgula no final. Assim, dentro da condição "se", quando o valor na posição i do vetor estiver entre 10 e 150, aux receberá o valor convertido em caracter (ex: se num[1] = 15, então aux = "15") e a variável frase será literalmente uma frase formada pela união dos caracteres já existentes antes na variável, mais o valor atual de aux e uma vírgula com um espaço na frente. Observe que isso tudo é basicamente o que você havia feito no seu programa, porém ao invés de escrever na tela todas as vezes que a função "para" completar um ciclo, eu guardo os valores dentro de uma variável do tipo "caracter". Observe que frase já havia recebido "Os números " antes de começar a receber os valores. Isso tudo ocorre apenas em: frase <- "Os números " para i de 1 ate 10 faca se (num[i] >= 10) e (num[i] <= 150) entao aux <- numpcarac(num[i]) frase <- frase + aux + ", " Agora pense dessa forma: Se os únicos números que você inserisse que fossem entre 10 e 150 fossem 3 números e todos os 3 de apenas 2 algarismos. Tomemos como exemplo os valores 20, 30 e 40. Quando terminasse o ciclo da função "para", a variável frase teria esse valor dentro dela: "Os números 20, 30, 40, ". Assim, irei utilizar da função "copia" para que a variável aux receba todos os caracteres da variável frase, exceto os dois últimos, que consistem em ", ", que é justamente a vírgula que você deseja tirar e mais o caracter espaço. Observe que em "Os números " existem 11 caracteres, sendo 9 letras e 2 espaços. Dessa forma, contando a partir do primeiro caracter numérico (no caso, o 2) até o último algarismo numérico, que é o logo antes da vírgula indesejada, você teria "20, 30, 40", que consiste em 10 algarismos, sendo 6 numéricos, 2 vírgulas e 2 espaços. Agora utilizaremos da parte de função, em matemática, mas nada complicado. Assim, podemos achar uma função "f(j) = 4j - 2", sendo que j é o número de algarismos entre 10 e 150 e f(j) o número de caracteres do primeiro algarismo numérico até o último antes da vírgula. No exemplo, podemos observar que temos 3 valores entre 10 e 150, sendo eles 20, 30 e 40. Assim, j = 3. Utilizando o j na função, achamos que f(j) = 4*3 - 2, então f(j) = 10. E esse f(j) é justamente o que achamos anteriormente na prática. Entretanto, essa função se aplica apenas se todos os valores entre 10 e 150 forem de 2 algarismos, o que nem sempre ocorre. Mas se fizermos separadamente uma segunda função para qual todos os algarismos entre 10 e 150 forem de 3 algarismos, utilizando da mesma lógica anterior, achamos a função g(k) = 5k - 2, onde k é a quantidade de números com 3 algarismos. Essa segunda função é quase idêntica à primeira, mudando apenas um número por conta do acréscimo de algarismo. Assim, você tem 2 funções que funcionam separadamente, mas o problema agora é juntá-las de forma que se obtenha apenas uma. E isso é bem simples. Tomemos por exemplo se em determinada vez no programa, existir 2 números de 2 algarismos e 3 números de 3 algarismos entre 10 e 150, como por exemplo os números 20, 30, 110, 120 e 130. Após passar pelo comando "para", a variável frase estaria da seguinte forma: frase = "Os números 20, 110, 30, 120, 130, " (veja que eles não estão necessariamente em ordem crescente ou decrescente). Novamente contando a partir do primeiro algarismo numérico até o último antes da vírgula, obtemos 21 caracteres. Entretanto, utilizando as funções que criamos separadamente, não é possível achar uma quantidade exata de caracteres antes da vírgula. Mas observe que se reagruparmos os valores, dessa forma em ordem crescente (ou decrescente, a lógica é a mesma), temos que frase = "Os números 20, 30, 110, 120, 130, " Se observarmos, fica claro que contando do primeiro algarismo numérico (no caso o algarismo 2 do número 20) até o último algarismo numérico do último número com a mesma quantidade de algarismos do primeiro (no caso o algarismo 0 do número 30), teríamos o valor encontrado utilizando a primeira função (f(j) = 4j - 2). Entretanto, ainda utilizaremos a vírgula e o espaço posterior, então simplesmente não retiramos esses 2 caracteres, sendo assim f(j) = 4j desta vez. Dessa forma, no exemplo, já teríamos contado todos os caracteres de "20, 30, ", que corresponde, justamente, a 8 caracteres. Ainda, observando agora os números com 3 algarismos, contamos do primeiro algarismo do primeiro número (no caso o 1 do 110) até o último algarismo do último número de 3 algarismos (no caso o 0 do 130). Observamos que corresponde a 13 algarismos, o que corresponde ao valor da segunda função (g(k) = 5k - 2) quando k = 3. Porém, dessa vez, nós desejamos retirar os últimos 2 caracteres, que são a vírgula e o espaço final. Assim, somando as 2 funções obtidas com essa lógica, temos uma nova função h(x) = 4j + 5k - 2. Também adicionamos os 11 caracteres iniciais de "Os números ", obtendo assim h(x) = 4j + 5j - 9. Essa função h(x) corresponde ao número de todos os caracteres até o último antes da última vírgula, que é justamente o que desejávamos. Depois dessa longa explicação, finalmente voltamos ao algoritmo. Entretanto, agora fica extremamente mais fácil de entendê-lo. Observe que no ciclo do comando "para", toda vez que o número escrito pelo usuário estiver entre 10 e 150, haverá 2 condições lógicas, sendo a primeira para ver se o comprimento do número é de 2 algarismos e a segunda para ver se o comprimento do número é de 3 algarismos. Se a primeira estiver correta, adicionamos 1 à variável j, que corresponde justamente à quantidade de números de 2 algarismos. Isso ocorre de forma análoga para a variável k na segunda condição. Veja que antes de começar o comando "para", ambas as variáveis receberam o valor 0, para evitar problemas futuros. Observamos isso em: j <- 0 k <- 0 se (compr(aux) = 2) entao j <- j + 1 senao se (compr(aux) = 3) entao k <- k + 1 fimse fimse Agora, após a função "para" acabar, existem 3 variáveis importantes: A variável j e k, que correspondem, respectivamente, à quantidade de números com 2 e 3 algarismos, e a variável frase, que possui a frase inteira que necessitamos para a saída do programa, porém ainda com a vírgula e o espaço final indesejado. Entretanto, como já criamos a função necessária, fica realmente fácil tirar esses 2 caracteres. Agora é o momento que a variável aux realiza sua segunda função, sendo esta a função de receber todos os carateres desejados da variável frase. Para isso, utilizamos a função "copia", que vai literalmente copiar os caracteres desejados. Assim: aux <- copia(frase:1:9+4*j+5*k) escreva(aux, " está(ão) entre 10 e 150.") Quando fazemos "frase:1:9+4*j+5*k", o algarismo 1, em laranja, significa que copiaremos a partir do primeiro caracter e a função em roxo significa o número de caracteres que iremos copiar. Assim, copiamos toda a parte desejável para a variável aux. Após isso, basta fazer um comando escreva, que escreverá tudo dentro da variável aux mais a parte " está(ão) entre 10 e 150.", terminando o algoritmo. Apenas para finalizar, observe a parte abaixo do algoritmo: se (j = 0) e (k = 0) entao escreva("Nenhum valor entre 10 e 150 foi adicionado.") senao aux <- copia(frase:1:9+4*j+5*k) escreva(aux, " está(ão) entre 10 e 150.") fimse Coloquei uma condição para ver se j e k são iguais a 0, pois se forem, quer dizer que não foi inserido nenhum valor entre 10 e 150. Desculpe pela extensão da resposta, apesar do algoritmo não ser tão complicado, não achei uma forma mais rápida de explicar. Espero que entenda a resolução.
  13. Era isso mesmo. Eu tinha até tentado colocar readln no "read(a);", mas não tinha funcionado, só depois vi que tinha que ser readln no "read(num);". Ontem quando estava procurando por soluções, achei esse mesmo post que você enviou, então entendi a diferença entre read e readln e deu certo o programa. Agora vou usar praticamente sempre o readln. Muito obrigado.
  14. Olá. Eu estava fazendo um programa que eleva um número real ao quadrado e depois pergunta se o usuário deseja elevar outro número. Porém, quando eu escrevo para ler a variável "a", do tipo string, em "read(a);" ela simplesmente não lê e continua o programa. Segue o programa completo: Program potencia; var num, q: real; a: string; r: boolean; Begin r := true; while r = true do begin write('Insira o valor a ser elevado: '); read(num); q := num*num; writeln('O quadrado de ', num:0:4, ' é igual a ', q:0:4, '.'); write('Você quer elevar outro número? (s - sim // n - não): '); read(a); if a = 'n' then r := false; end; End. Dessa forma, a variável "r", do tipo boolean, sempre fica como true e o programa vira um loop infinito, onde o usuário consegue continuar elevando números, mas nunca pode digitar "n" para sair do programa. Alguém poderia me dizer o motivo?

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...