Eu tive um problema de compilação com o EP4 e falei com o Reverbel. O alerta é para quem estiver usando DEV C++ na configuração padrão com Windows XP. Poderá haver um estouro de memória quando se declarar um array dentro de uma função com valor de 512. Veja o pedaço de código abaixo:
/* --------------------------------*/
#define MAX 512 /* dimensao maxima */
int main() {
int m, n, maxval;
int a[MAX][MAX];
(...)
/* --------------------------------*/
Isto dá um BAITA erro no Windows. A solução (depois o prof explica direito) é colocar um STATIC conforme abaixo ou diminuir o máximo até que não ocorra o estouro:
/* --------------------------------*/
#define MAX 512 /* dimensao maxima */
int main() {
int m, n, maxval;
static int a[MAX][MAX];
(...)
/* --------------------------------*/
/* ----------------------------------------------
Funcao que le um arquivo no formato PGM.
fname : nome do arquivo PGM
M : matriz correspondente a imagem lida
*m : numero de linhas da matriz
*n : numero de colunas da matriz
*maxval : maior valor na matriz
---------------------------------------------- */
int read_pgm(char fname[], int M[][MAX], int *m, int *n, int *maxval);
eu gostaria de saber porque eu tenho q tratar o m, n e maxval como ponteiros se eu naum vou mudar o seu valor ao longo do programa????
Certo?
é q eu pensava q eu teria q colocar no main o mesmo q ta escrito como exemplo no enunciado do ep....
entaum quer dizer q eu posso fazer uma função pra ler do jeito que eu quiser (seguindo o exemplo), mas naum preciso ter exatamente ele no main???
isso é normal??
fprintf(arq, "# imagem sem ruido\n");
Mas se a gente tenta abrir a imagem que já fizemos o tratamento, nosso programa não trata esse tipo de linha. É pra tratar?
Artur
fprintf(arq, "# imagem sem ruido\n");
Mas se a gente tenta abrir a imagem que já fizemos o tratamento, nosso programa não trata esse tipo de linha. É pra tratar?
Artur
Já que o Artur comentou...
devemos considerar que o arquivo pgm de entrada contenha algum comentario, a ser ignorado na leitura? ou parte-se do pressuposto que há apenas o P2, a dimensao, o valor maximo e a matriz?
(tenho q impressao que estou fazendo a mesma pergunta que ele...)
O que complica um pouco o tratamento de comentários é que eles podem aparecer em qualquer lugar, não necessariamente no início de uma linha. Um comentário começa com o caractere '#' e acaba no próximo new line. Todos os caracteres desde o '#' até o new line seguinte (inclusive esse new line) devem ser ignorados. Ou seja, dá na mesma escrever
12# comentario no meio de um numero!!!
34
ou escrever
1234
É mais fácil pensar no tratamento de comentários se a gente supõe que eles aparecem sempre no início de linha, ou pelo menos que eles não aparecem no meio de um número ou de uma palavra (poderia haver um comentário no meio do "P2"). Mas não é muito difícil aceitar comentários em qualquer lugar! Dica para quem quiser tratar comentários: olhem a função ungetc, definida em <stdio.h>. Essa função facilita bastante o tratamento de comentários em qualquer lugar.
Artur
P2 5 4 16 9 4 5 0 8 10 3 2 1 7 9 1 6 3 15 1 16 9 12 7
O seguinte arquivo pgm é equivalente ao arquivo acima:
P2 5 4 16 9 4 5 0 8 10 3 2 1 7 9 1 6 3 15 1 16 9 12 7
O que interessa é que depois das linhas
P2 5 4 16vem uma lista com 5 * 4 = 20 números, que são os elementos da matriz. Os primeiros cinco números dessa lista formam a primeira linha da matriz, os próximos cinco números formam a segunda linha, e assim por diante. A lista de 20 números poderia aparecer toda na mesma linha, ou com um número por linha (formando uma só coluna), ou em qualquer outra disposição. Claro que é interessante dispor essa lista como uma matriz (afinal ela é a lista dos elementos de uma matriz 4x5), mas isso não é obrigatório!
Talvez o seu programa esteja exigindo que a lista venha disposta como matriz. Note que é mais fácil ler a lista de números sem exigir que ela venha arranjada de modo matricial! Basta usar um "%d" para ler cada número, em vez de fazer alguma coisa mais complicada que leve em conta a presença de caracteres new line e a posição desses caracteres no arquivo de entrada.
Artur
Prof, tem algum site bom para baixar mais exemplos de pgm's sujas?
vou anexar a imagem que eu fiz.
professor sera q vc poderia testar limpar a imagem kid pra ver se o erro é com o nossa programa mesmo??
Então é isso mesmo?
toda a parte de conferir o arquivo de entrada pode ser colocado na função read_pgm?
caso não, porque o cabeçalho inclui a string com o nome do arquivo e não um ponteiro para o próprio arquivo?
outra coisa... o enunciado pede para imprimir na tela a matriz caso a imagem seja menor que 16x16... mas o que é considerado "menor" que isso?
Quanto à outra coisa... (O que é considerado "menor" que 16x16?) Boa pergunta! Vamos considerar "menores" que 16x16 as imagens que tem as duas dimensões menores ou iguais a 16. Assim, 10x15 e 16x16 são "menores" que 16x16, mas 4x17 não é.
O programa deve exibir erro caso o usuario digite um "p" ou "q" par, ou podemos considerar um usuario ideal?
Oi. É..... talvez eu esteja enganada, tenha me confundido com alguma coisa.... mas, no enunciado do ep, diz que a matriz A tem M linhas e N colunas. Na explicaçao da leitura do arquivo de entrada, diz que os dois numeros que aparecem sao respectivamente o numero de colunas e de linhas e portanto N e M. Entretanto, no exemplo de leitura do arquivo de entrada, esses dois numeros sao armazenasdos em M e N, nesta ordem, e portanto, linhas e colunas.
É isso. Creio que alguma coisa esta trocada e estou meio confusa por causa disso.
Artur
hahahahahahah!!! beleza beleza!!
OBS: prof, acho que eu mereço um bonus hein!!!!!!
sera q vc poderia explicar melhor???
pra contornar esse problema, na leitura temos q alterar para:
aux = fscanf(arq, "%d %d %d", &*n, &*m, &*maxval);
if (aux != 3) {
printf("Formato incorreto\n");
fclose(arq);
exit(1);
}
e na escrita, para
fprintf(saida, "P2\n%d %d\n%d\n", n, m, maxval);
No arquivo PGM o número de colunas é o que aparece primeiro, depois vem o de linhas. Você não pode mudar isso, mas você tem toda liberdade de, no seu programa, chamar esses dois números de n (colunas) e m (linhas), ou de m (colunas) e n (linhas), ou outra coisa.
Infelizmente o enunciado não está usando os nomes m e n de forma consistente. A seção 1 usa m para linhas e n para colunas. Os protótipos das funções read_pgm e write_pgm também usam m para linhas e n para colunas. Mas o programa-exemplo, na seção 4, saiu com m para colunas e n para linhas... Por consistência com o resto do enunciado, teria sido melhor usar m para linhas e n para colunas também no programa-exemplo. Do jeito que está não é errado, mas o enunciado fica menos claro e induz a erros.
Duas possibilidades, ambas aceitáveis:
- apresentar uma mensagem de erro, ou
- silenciosamente converter em m um valor de p que seja maior que m e converter em n um valor de q que seja maior que n.
aux = fscanf(arq, "%d %d %d", &*n, &*m, &*maxval);
if (aux != 3)
{
printf("Formato incorreto\n");
fclose(arq);
return 0;
}
mas ele sempre mostra incorreto, alguem pode me ajudar?
/*função que le um arquivo, no formato PGM*/
int read_pgm(char fname[], int M[] [MAX], int *m, int *n, int *maxval)
{
FILE *arq;
char key[128];
int aux, i, j;
/* abre arquivo para leitura */
arq = fopen(fname, "r");
if (arq == NULL) {
printf("Erro na abertura do arquivo %s\n", fname);
exit(1);
}
/* le dados do cabecalho */
aux = fscanf(arq, "%s", key);
if (aux != 1) {
printf("Erro na leitura do arquivo %s\n", fname);
fclose(arq);
exit(1);
}
if (strcmp(key, "P2") != 0) {
printf("Formato desconhecido\n");
fclose(arq);
exit(1);
}
aux = fscanf(arq, "%d %d %d", &*n, &*m, &*maxval);
if (aux != 3) {
printf("Formato incorreto\n");
fclose(arq);
exit(1);
}
........(neste ponto existe a leitura da matriz, mas eu omiti para colocar no forum)
fclose(arq);
return 0;
}
As funções fscanf, scanf e sscanf devolvem o valor total de items que combinam com o que você coloca entre aspas dentro dela.
Os espaços que você colocou ali têm que bater com o que está no arquivo de leitura.
/* le dados do cabecalho */
aux = fscanf(arq, "%s ", key);/*.............aqui ele le o nome P2 e me devolve corretamente, depois tem um espaço para pular a linha, jah tentei sem o espaço tambem..................*/
if (aux != 1) {
printf("Erro na leitura do arquivo %s\n", fname);
fclose(arq);
return 0;
}
if (strcmp(key, "P2") != 0) {
printf("Formato desconhecido\n");
fclose(arq);
return 0;
}
aux = fscanf(arq, "%d %d %d", &*n, &*m, &*maxval);/*.......aqui são lidos, m, n e maxval, mas os valores devolvidos não são corretos............*/
printf("m=%d, n=%d, mv=%d, aux= %d, key=%s", *m, *n, *maxval, aux, key);
/*......aqui me devolve na tela os valores tenho:
Digite o nome do arquivo de entrada: cameraman.pgm
m=16, n=2303112, mv=2294120, aux= 0, key=P2(<<<que esta correto)Formato incorreto
Digite o tamanho da vizinhanca (p q):
...........*/
if (aux != 3) {
printf("Formato incorreto\n");
fclose(arq);
return 0;
}
No arquivo que você está usando como entrada, provavelmente não há espaços entre o m, o n, e o maxval.
Para evitar estes tipos de problemas você poderia escanear os %ds separados, usando apenas "%d", deste jeito o fscanf sairá procurando um inteiro para pegar no stream do arquivo, não importando se há espaços, \ns ou, cuidado, comentários entre eles.
Eu praticamente ja tava com o ep todo pronto (as fotos tavam ficam legal) qdo resolvi testar com o exemplo q ta no ep...
9 | 4 | 5 | 0 | 8 |
10 | 3 | 2 | 1 | 7 |
9 | 1 | 6 | 3 | 15 |
0 | 3 | 8 | 10 | 1 |
1 | 16 | 9 | 12 | 7 |
onde a mediana dava:
0 | 0 | 0 | 0 | 0 |
0 | 5 | 3 | 5 | 0 |
0 | 3 | 3 | 6 | 0 |
0 | 6 | 8 | 8 | 0 |
0 | 0 | 0 | 0 | 0 |
soh q eu nao consigo de forma alguma entender como a vizinhança
10 | 3 | 2 |
9 | 1 | 6 |
0 | 3 | 8 |
consegue ter como mediana o numero 3? Q conta foi usada?
falta tlvz soh isso preu poder ver o q falta corrigir ou nao no ep
Grata
Fique sossegado, (provavelmente!) funcionará!
Achei q fazer o programa ler figuras com comentarios dava um extrinha de ponto..
Pq apesar do warning q nao apareceu aqui no dev (warning exatamente pq quis fazer ler figuras com comentarios) funciona perfeitamente..
Alias, alem de ninguem testar o dev pra ver os warnings q o povo ta reclamando q tao descontando e nao ocorrem.. (e continuam a descontar.. ) como o monitor pode descontar um ponto de algo q ele mesmo erra?
Ele me descontou por nao estar com a biblioteca "ctype" por causa do atoi.. sendo q pelo proprio site que vcs passaram:
http://www.cplusplus.com/reference/clibrary/cstdlib/
ele pertence a bilbioteca "stdlib"?
Retirei o stdlib qdo retirei o system("pause") e testei novamente e funcionou... ta na hora de vcs darem uma olhadinha no q ta acontecendo com o dev.. no meu caso nao vai ter problema.. mas pode ter aluno q nao ta indo tao bem nos eps por causa de warnings q o programa indicado nao esta dando..
Desculpem, mas fico pensando nos alunos q podem estar precisando dos minimos de pontos descontados por causa de warnings inexistentes..
Quem eu tive que tirar dois ou mais lugares eu não dei o ponto extra.
Mas no meu caso eu testei colocando 4 comentarios diferentes e ele leu normalmente..
E nao tive nem meio ponto extra..
Nancy, estou colocando anexado a este post a imagem que eu usei como teste.
No seu caso ele não reconhecia a extensão da imagem sem retirar o primeiro comentário, e depois de retirá-lo, o programa entrava em loop infinito para ler a imagem.
Para constar: ela abre normalmente no "eog", eye of gnome, um visualizador de imagens para o linux, e também no "irfanview" um visualizador de imagens para windows.
________________________
P2#
15#so para atrapalhar
15
70
...
________________________
eu preciso eliminar o comentario e NAO juntar o 15 com o 15. Ou seja, tenho que trocar o \n por um branco.
Por outro lado, é possível ter um comentário no MEIO de uma informação? Assim, por exemplo?
________________________
P2#
1#esse é pra detonar
5 15
70
...
________________________
Aí eu não posso colocar o branco e tenho que eliminar TODO o comentario, inclusive o new line.
A rigor, pelo que entendi, um sujeito pode colocar um comentário no meio dos dados da imagem...
Tem uma dica de como usar o ungetc? Eu tentei fazer por aí, mas pelo que entendi ele trabalha com o buffer da memória, e voce consegue trocar o caracter referenciado por outro. Mas não consegui imaginar como usar isso.
Como fazer?
Artur
Na especificação do arquivo tipo pgm a única anotação sobre \n's são com respeito aos comentários. Eles sinalizam um final de comentário.
Estou colocando uma versão do feep.pgm anexado a este post que lhe mostra como um arquivo.pgm também pode ser escrito (sem perder informações sobre a imagem). Abra ele em um editor de texto para ver a diferença que não faz diferença.
Em relação ao ungetc ele serve para você devolver para o stream do arquivo algum byte (char). Deste modo se você encontrasse um número, pegando char por char e quisesse saber onde ele termina, você poderia pegar um por um e quando encontrasse algo que não fosse número, e você tiver certeza que o número terminou ali, então devolver tudo para o stream (os números, como se estivesse desempilhando-os) e pegar de uma vez um %d.
Mas eu acho que o que o professor quis dizer e que se você passasse pelo FILE todo, retirando ele os comentários (usando ungetc - você pode colocar um byte diferente do que realmente estava lá inicialmente-, sem precisar reescrever em outro lugar, como você fez) e daí passar pelo arquivo como você faria normalmente com um arquivo sem comentários.