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

Problemas Com Fscanf E Chars Longas


Heldinho

Pergunta

Bom pessoal, olha só.. eu queria saber porque que no meu programa quando eu uso scanf, quando ele acha um " "(espaço), ele pensa que é o fim do arquivo e não scaneia mais nada pra frente?? olha, fiz um exemplo pra mostrar:

arq.c:

#include <stdio.h>

void main(void){

FILE *arq;

char conteudo[9000]; /* Tem como por um valor não definido aki(infinito) ?? mais tarde terei que usar while conteudo != NULL (no meu outro código)*/

arq=fopen("arq.c","r");

fscanf(arq,"%s",&conteudo);

printf("%s",conteudo);

}

compilem este programa, coloquem o arq.c na mesma pasta, e executem ele.. só vai aparecer #include na tela. e o resto do código!? :S

espero que vocÊs tenham entendido minha duvida.. não postei realmente o código do meu programa, pois não sei se este é o unico bug dele.. ai seria abuso, não? até + =)

Link para o comentário
Compartilhar em outros sites

19 respostass a esta questão

Posts Recomendados

  • 0

Bom cara, talvez o fread funcione.. não tenho nem idéia de como usa-lo :S.. bom, o que eu quero fazer no meu programa, é um programa que conte quantas linhas(; e #) algum código fonte tenha.. não me digam como fazer, por favor, eu realmente gostaria de descobrir tentando, porém não estou conseguindo fazer esta parte de pegar o arquivo todo e passar para uma variavel :S.. bom.. quem souber ajudar =) até mais wink.gif

Link para o comentário
Compartilhar em outros sites

  • 0

Seu raciocínio estava no caminho certo... Mas algo deve ter desviado um pouco sua atenção e fazer com que seu raciocinio desvie um pouco do caminho certo...

O programa que você postou aqui, usa uma string para armazenar o conteúdo e você lê os dados do arquivo como se fosse uma string. Veja agora que o modifiquei como ele funciona:

#include <stdio.h>

void main(void)
{
   int i = 0;
   FILE *arq;
   char conteudo[9000];
   arq=fopen("arq.c","r");
   for (i = 0; !feof(arq); i++) {
      fscanf(arq,"%c",&conteudo[i]);
      printf("%c",conteudo[i]);
   }
}

Note que um loop foi adicionado para detectar o fim de arquivo com a função feof(FILE *), que retorna um valor true quando o fim de arquivo é encontrado.

Link para o comentário
Compartilhar em outros sites

  • 0

Cara, eu nunca poderia imaginar que uma simples leitura de char em char poderia resolver o meu problema.. vlw mesmo =).. outra coisa.. lá na variavel conteudo[9000];, tem como colocar um valor infinito de chars? eu já tentei conteudo[];, mas o compilador diz que não especifiquei um tamanho para a variavel, e o maior que consegui é 999999 . mas mesmo assim, obrigadão =)

Link para o comentário
Compartilhar em outros sites

  • 0

Não, não seria possível alocar um array de infinito de caracteres, pois o compilador deve reservar um espaço para esse array e não poderia reservar todo o espaço, mesmo porque ele é limitado e outros programas precisam dele. Mas o que pode ser feito é contar o numero de caractéres e alocar dinamicamente o array com malloc. Se quiser um exemplo, é só pedir que eu tentarei faze-lo para você.

Link para o comentário
Compartilhar em outros sites

  • 0

Bom... Demorei um pouco porque tive que resolver um problema, custei a ententer que devia salvar o arquivo com extensão .c. Mas esta aí:

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

int main(void)
{
   int i;
   int a;
   FILE *arq;
   char *conteudo;
   arq = fopen("arq.c","r");
   for (i = 0; !feof(arq); i++) {}    /*Loop vazio... Só para contar os caracteres na variável i .*/
   conteudo = malloc(i*sizeof(char)); /*Aloca dinâmicamente a string.*/
   free(conteudo);                    /* Liberta a memória alocada por malloc .*/
  
   return 0;
}

A função malloc de stdlib.h , recebe um argumento que é o tamanho em bytes do ponteiro(array é um ponteiro) a ser alocado. Então passamos o argumento (i*sizeof(char)), que significa que é para alocar i veses o tamanho em bytes(1 byte = 8 bits) de uma veriável do tipo char, sendo i o número de posições da string.

Link para o comentário
Compartilhar em outros sites

  • 0

bom, o que eu quero fazer no meu programa, é um programa que conte quantas linhas(; e #) algum código fonte tenha..

Observação: nesse caso, você não contaria quantas linhas tem em um código fonte em C / C++, você contaria quantos comandos existem, pois um comando pode ser escrito em mais de uma linha.

Link para o comentário
Compartilhar em outros sites

  • 0

lá na variavel conteudo[9000];, tem como colocar um valor infinito de chars? eu já tentei conteudo[];, mas o compilador diz que não especifiquei um tamanho para a variavel, e o maior que consegui é 999999 .

Bom... Tem um jeito de fazer mais ou menos o que você quer... Mas é muito perigoso e pode resultar em uma mensagem pentelha de erro se usar um espaço na memória que é destinada para qualquer coisa que não seja dados do programa(mas teria que ter bastante elementos para isso)... Se você declarar um array como:

char *str;

Teremos um ponteiro que aponta para um espaço na memória, supondo 0001:0000 , se você incrementa 1 a esse ponteiro ele apontará para o endereço seguinte que no caso seria 0001:0001. Pode-se incrementar quanto quiser...

Veja mais ou menos como funciona:

ENDEREÇO ------ VALOR

0001:0000 -------- 45 -> posição inicial do ponteiro.

0001:0001 -------- 57

0001:0002 -------- 63

0001:0003 -------- 49

Portanto, ao incrementarmos 1 ao ponteiro(que está apontando para 0001:0000) ele apontaria para o endereço onde tem como valor 57, se incrementássemos mais 2 ele apontaria para 0000:0003 onde tem o valor 49.

Todos esses valores podem estar sendo usado por qualquer outro programa ou até mesmo pelo Windows(ou qualquer outro OS). Por isso é muuito perigoso e nem um pouco recomendável fazer isso e muito menos modificar o valor, a menos que saiba muuuito bem o que está fazendo.

Link para o comentário
Compartilhar em outros sites

  • 0

Vale dizer que depende do tipo de dado. Como char só ocupa um espaço na memória, incrementando, sim, você está indo para a posição 0001:0001, mas se fosse de inteiros, você estaria indo para a posição 0001:0004, pois os inteiros ocupam 4 posições( tá, podemos dizer bytes ) na memória.

O nome de um array é apenas um ponteiro para sua primeira posição.

Quando o compilador encontra um array, ele pega quantos bytes ocupa cada dado( pelo tipo ), e então, quando você for para o próximo item do array, ele sabe quantos bytes pular.

Se você estivesse fazendo isso em C++( ia ficar mais pesado ), dá pra você direitinho usar exatamente a memória necessária, pois você descobriria quantos caracteres tem o arquivo, e com C++, pode você criar variáveis em qualquer parte do código, podendo criar, depois de descobrir o tamanho do arquivo, um array de chars com tamanho exato. wink.gif

Desculpe-me por ser chato, mas muitos programadores recomendam o não uso de malloc, não sei por que.

Link para o comentário
Compartilhar em outros sites

  • 0

Ae gente, muito obrigado mesmo.. consegui fazer um programa que conta quantas variaveis, funções, linhas, comentários e headers ele tem =) olhem só o código fonte:

#include <stdio.h>
#include <conio.h>
#include <funcoesh.h>

void main(void)
{
  int i = 0;
  FILE *arq;
  int total;
  int totalc;
  int pontoev;
  int variaveis;
  int comentarios;
  int jogodv;
  char conteudo[99999];
  char arquivo[255];
printf("Digite o nome do arquivo:");
scanf("%s",arquivo);
  arq=fopen(arquivo,"r");
  for (i = 0; !feof(arq); i++) {
     fscanf(arq,"%c",&conteudo[i]);

  }
printf("\nCarregando o arquivo...\n");
delay(1000); /* só pra fazer uma horinha com o cara.. qual a graça sem isso!??!?! rsrsrsrsrs */
printf("%s",conteudo);
totalc = i-1;
printf("%d",totalc);
i=0;
jogodv=0;
variaveis=0;
comentarios=0;
while(i<totalc){
if(conteudo[i] == ')' && conteudo[i+1] == ';'){
pontoev++;
}
if(conteudo[i] == ';' && conteudo[i-1] != ')' && conteudo[i-1] != '+' && conteudo[i-1] != '=' && conteudo[i-1] != '-'){
variaveis++;
}
if(conteudo[i] == 'i' && conteudo[i+1] == 'n' && conteudo[i+2] == 'c' && conteudo[i+3] == 'l' && conteudo[i+4] == 'u' && conteudo[i+5] == 'd' && conteudo[i+6] == 'e'){
jogodv++;
}
if(conteudo[i] == '*' && conteudo[i+1] == '/'){
comentarios++;
}
if(conteudo[i] == '/' && conteudo[i+1] == '/'){
comentarios++;
}
if(conteudo[i] == '\n'){
total++;
}

i++;
}
total = total+1;
fclose(arq);

limpa(12); /* Limpa a tela e põe a cor vermelha como fundo */
janela(5,5,70,20," Counter Plus - Created By Helder de Oliveira Gomes Filho."); /* Cria um quadrado nas seguintes cordenadas: x1=5 y1=5 até x2=70 e y2=20  com o titulo Created By... */

textbackground(BLUE);
textcolor(YELLOW);
gotoxy(6,7);
cprintf("Relatorio do arquivo:");
gotoxy(6,8);
cprintf("Numero total de funcoes: %d",pontoev);
gotoxy(6,9);
cprintf("Numero total de variaveis: %d",variaveis);
gotoxy(6,10);
cprintf("Numero total de linhas: %d",total);
gotoxy(6,11);
cprintf("Numero total de Headers: %d",jogodv);
gotoxy(6,12);
cprintf("Numero total de comentarios: %d",comentarios);
gotoxy(6,18);
cprintf("Creditos para DOUPLUS e ARAGORN13. =)");
gotoxy(5,20);
textcolor(WHITE);
pausa("");
limpa(0); /* limpa a tela com cor de fundo preto */

gotoxy(0,0);

}
Xii, e agora?? eu inclui a funcoesh.h e você não tem ela.. bom, funçõesh.h é uma header que eu criei a muito tempo atraz, e aproveitei pra usa-la neste programa para deixa-lo mais bonito.. você pode retirar as funções da funcoesh.h que estão no código fonte, ou pode colocar isso na sua pasta include: funcoesh.h:
#include <stdlib.h>
#include <conio.h>
#include <string.h>
/*
Funcoesh.h - Um conjunto de funções para a linguagem de programação C desenvolvida
por Helder de Oliveira Gomes Filho.
Funcoes.h contém funcões relacionadas ao vídeo, como linhas(); que serve para escolher
o numero de linhas na tela, cls(COR); que serve para limpar a tela e deixar o fundo colorido
, também têm funções relacionadas à Janelas em 3D.Sem contar a barra de carregamento com porcentagem.
© Web Hosting Brasileiro.           ¯¯¯¯¯¯¯¯¯¯¯¯¯              ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
PS:As funções são todas em língua portuguesa, para facilitar aos programadores iniciantes em C.

Editado -------
Este Atenção Abaixo, só vale se seu compilador for muuuuuito antigo!? ahh seila.. não dê mta bola pra esse atenção ai não.

ATENÇÃO!
Este Header só funcionará quando você incluir os seguintes arquivos ao seu programa:
#include <stdio.h>
#include <conio.h>

e é obvio que também tem que incluir a header:
#include <funcoesh.h>


O arquivo funcoesh.h é freeware.
Eu somente peço que coloque meu nome nos créditos de seu programa.

*/

void janela(int a, int b, int a1, int b1, char * titulo){ /* Função janela. modo de uso: janela(coluna em que a janela inicia, linha em que a janela inicia, coluna em que a janela acaba, linha em que a janela acaba, "Título da janela"); */
int x,y,x2,y2,z,zz,x3,y3,z3,x4,y4,z4,z5;
x=a;
y=b;
x2=a1;
y2=b1;
z=x;
zz=y;
x3=x+1;
y3=x2+1;
z3=y2;
x4=y+1;
y4=y2+1;
z4=x2;
z5=z;

while(x<x2){
while(y<y2){
gotoxy(x,y);
textbackground(BLUE);
cprintf(" ");
y++;
}
y=b;
x++;
}
textbackground(WHITE);
while(z<x2){
gotoxy(z,zz);
cprintf(" ");
z++;
}
textbackground(BLACK);
while(x3<y3){
gotoxy(x3,z3);
cprintf(" ");
x3++;
}
while(x4<y4){
gotoxy(z4,x4);
cprintf(" ");
x4++;
}
gotoxy(z5,zz);
textbackground(WHITE);
textcolor(BLACK);
cprintf("%s",titulo);
}

void tlinhas(int d){     /* Função tlinhas - Tanto de Linhas na tela. O parâmetro a pode ser somente 25 ou 50. */
if(d==25){
system("MODE CON LINES=25");
}
else if(d==50){
system("MODE CON LINES=50");
}
}

void limpa(int c){ /* Função limpa - limpa a tela e coloca o fundo de uma cor.modo de uso: limpa(numero da cor); */
int x=0;
textbackground(c);
while(x<100){
cprintf("\n");
x++;
}
}
/*  -- Tabela de cores
Veja aqui abaixo o numero de cada cor para a função limpa:
0  -    BLACK,          -- dark colors --
1  -    BLUE,
2  -    GREEN,
3  -    CYAN,
4  -    RED,
5  -    MAGENTA,
6  -    BROWN,
7  -    LIGHTGRAY,
8  -    DARKGRAY,       -- light colors --
9  -    LIGHTBLUE,
10 -    LIGHTGREEN,
11 -    LIGHTCYAN,
12 -    LIGHTRED,
13 -    LIGHTMAGENTA,
14 -    YELLOW,
15 -    WHITE
 -- Fim da Tabela de Cores.OBS: nenhuma função precisa de comentários para funcionar. coloquei eles aqui só para ajudar a acostumar com as novas funções. */


void irpara(int a, int b){ /* Função irpara() - Sinônimo de gotoxy(). Do mesmo mode que gotoxy, o parâmetro a é a coluna em que o cursor vai ficar, e o parâmetro b é a linha que o cursor vai ficar. ex: irpara(15,5); Isto faz com que o cursor vá para a coluna 15 na linha 5. */
gotoxy(a,b);
}

void escrevec(char * frase){ /* escrevec(Escreve Colorido) - Função sinônima de cprintf(), porém não aceita mostrar variáveis.modo de uso: escrevec("Frase/texto/palavras.."); */
cprintf(frase);
}

void pausa(char * fpausar){ /* pausar() - Uma função bastante útil para interromper o programa e continuar a execução apos pressionar a tecla [ENTER].Observe que ela possui um parâmetro (fpausar), ele serve mara mostrar uma frase enquanto o programa está sendo pausado. ex: pausa("Aperte algo para voltar ao programa"); */
escrevec(fpausar);
irpara(1,1);
getche();
}

int sair(char * titulo, char * texto, int cor){ /* sair() - É uma função para quem quer que o usuário fique mais no seu programa. quando ela é executada, aparece uma janela com um titulo , um pequeno texto e um botao sim e não. se a pessoa apertar sim, o programa para de ser executado, se a pessoa apertar não, o programa continua a ser executado(apenas o código seguite da funcao sair() ).Modo de uso: sair("Título do programa","pequeno texto",numero da cor de fundo do seu programa); .Exemplo: sair("EasyDosBR 2","Deseja mesmo sair?",4); . para entender melhor a função, olhe o exemplo chamado sair.cpp . */

char ch;
limpa(cor);
janela(10,5,30,10,titulo);
irpara(15,9);
textbackground(RED);
textcolor(WHITE);
escrevec("SIM");
irpara(10,6);
textbackground(BLUE);
textcolor(WHITE);
escrevec(texto);
irpara(15,9);
textbackground(RED);
textcolor(YELLOW);
cprintf("S");
irpara(20,9);
textcolor(WHITE);
escrevec("NÇO");
irpara(20,9);
textcolor(YELLOW);
escrevec("N");
while(1){
irpara(15,9);
ch=getche();
if(ch=='s'){
limpa(cor);
exit(0);
}
else {
limpa(cor);
return 0;
}
}

}


/* Atenção! Esta é uma versão beta. Nem tudo que foi  */
/* dito no começo do programa está aqui.Aguarde novas */
/* atualizações no portalc ou na whbr.                */
/* © 2004 By Helder & WHBR Corp. - www.whbr.cjb.net   */
/* Fim do arquivo funcoesh.h . eu espero ter ajudado  */
/* com este arquivo, e espero também que você coloque */
/* meu nome nos créditos.                             */

Bom, imagino que o programa esteja cheio de bugs.. se alguém encontrar algum, me avise, ahh, obrigado mais uma vez a todos vocês qu eme ajudaram com o fscanf !!

Link para o comentário
Compartilhar em outros sites

  • 0

Bem observado aragorn13!

É recomendável usar new ao invés de malloc porque diferente do malloc, new retorna um ponteiro do tipo especificado pelo o usuário, já malloc retorna sempre um ponteiro void*, a não ser que haja um erro na alocação(mas isso não vem ao caso). Tanto, que se compilar o exemplo que postei com o gcc(delorie) ou o Dev-C++, a menos que a extensão do arquivo seja .c, o compilador acusará um erro por conversão inválida de void* para char*. Me parece que C++ não admite isso, pois a extensão .cpp cousou um erro.

EDIT: Putz... Postei junto com o Heldinho, era para aparecer depois desse ultimo post do aragorn13, mas acho que deu para entender...

Link para o comentário
Compartilhar em outros sites

  • 0

Mas é muito importante você entender a parte de memória, já que você está fazendo um OS, não está? biggrin.gif

E o Douplus já explicou o porque de não ser bom usar o malloc.

Aliás, adivinha por que você não pode criar um array de void? Adivinha!

Porque o computador não sabe quantos bytes pular para chegar ao próximo item do array ( void é um tipo "indefinido" ). Aliás, poder eu acho que pode, mas vai dar uma bugalhada só.

Bem que a gente queria um tipo Variant como no VB às vezes. cool.gif

Link para o comentário
Compartilhar em outros sites

  • 0

Bom... Darei uma estudada no seu programa... Qualquer coisa é só falar comigo por:

char *email = "yenxp@hotmail.com";
   char *MSN = email;
   int ICQ[9] = {1, 5, 0, 9, 7, 8, 9, 2, 3};

Também se quiser uma explicação melhor sobre esses conceitos de momória é só entrar em contato.

EDIT: Affe... Desta vez postei junto com o aragorn13...

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

  • 0

pois é.. estou criando um os sim.. e ai que está o maior dos bugs dele.... a memória! sad.gif acho que tem a ver com a memória.. no windows, ele roda com uma velocidade belezinha.. no dos, quando eu clico no menu "iniciar"(whbros), ele demora uns 2 segundos pra abrir o menu.. V se pode.. não sei se tenho que carregar algum gerenciador de memória antes de entrar no OS, não sei se tenho que colocar funções relacionadas a memoria no meu OS.. seilá.. isso o "tempo vai concertar" !?!? =).. bom, agradeço mais uma vez vocês q tãum me ajudando muito =)

PS: não posso deixar de postar isso:

whbros.c(modo grafico do meu OS - v 0.0.8):

Relatorio do arquivo:

Numero total de funcoes: 351

Numero total de variaveis: 173

Numero total de linhas: 1003

Numero total de Headers: 6

Numero total de comentarios: 34

easy2.c (modo texto do meu os - versão 2.0.7):

Relatorio do arquivo:

Numero total de funcoes: 96

Numero total de variaveis: 145

Numero total de linhas: 407

Numero total de Headers: 3

Numero total de comentarios: 2

agora não pergunte se esses numeros estão certos =)..

Editado: eu q postei junto com DOUPLUS!!

Link para o comentário
Compartilhar em outros sites

  • 0

Eita... Vamos parar de postar junto. Respirem, apertem F5, e aí sim postem tongue.gif

Cara eu preciso ver o seu OS tongue.gif

Tipo eu queria ver o código pra ver como você fez, e também rodando. Nunca vi um OS feito por uma pessoa que não seja um cara da MS ou da SUN.

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,3k
×
×
  • Criar Novo...