FrostPt Posted August 3, 2012 at 12:53 AM Report Share #471343 Posted August 3, 2012 at 12:53 AM (edited) Boas, este é o meu primeiro post aqui no forum 😄 espero não fazer má figura :O Especialmente porque ainda sou um bocado nabo a programar em C. Vá, agora coisas sérias, tenho um pequeno problema num código que escrevi. Basicamente só preciso que leia de uma string se tem números ou não. O problema é que estou a trabalhar com ficheiros o que me anda a baralhar um bocado. Enfim é melhor meter o código, para perceberem o que quero dizer. #include <stdio.h> #include <stdlib.h> #define MAX_Linha 200 int main() { FILE *texto; FILE *texto_dig; int n, i, m; char string [MAX_Linha]; /* 1. abra arquivo texto.txt para leitura */ texto = fopen("texto.txt","r"); if (texto == NULL) { printf("Erro na abertura do arquivo texto.txt.\n"); exit(-1); } /* 2. abra arquivo texto_dig para escrita */ texto_dig = fopen("texto_digito.txt","w"); if (texto_dig == NULL) { printf("Erro na abertura do arquivo texto_digitado.txt.\n"); exit(-1); } fscanf(texto,"%d", &m); for (i = 0; i<m; i++) { if (fgets (string , MAX_Linha , texto) != NULL) { fscanf(texto,"%d", &n); if (n != 0) { fprintf(texto_dig,"%s", string); } } } /* 6. feche o arquivo texto.txt */ fclose(texto); /* 7. feche o arquivo texto_dig */ fclose(texto_dig); return 0; } Pensei meter na linha 34, em vez de 'texto', mudar para 'string' mas parece piorar :/ Erros/Avisos: Não dá nenhum Problemas/Inconvenientes: Não lê números nas strings do ficheiro de texto Enunciado: Desenvolva um programa que leia um ficheiro de texto (texto.txt) e imprima num outro ficheiro (texto_digito.txt) todas as linhas que tiverem pelo menos um dígito, imprimindo no final no ecrã o total de linhas nessas condições. Se o ficheiro inicial não existir, deverá imprimir zero. As linhas não têm mais de 200 caracteres cada. (O código ainda não está completo) Obrigado, desde já a quem possa ajudar. Deêm-me um desconto se o erro for obvio ainda dou bastante inexperiente 😞 Edited August 3, 2012 at 08:37 AM by pmg pastebin nao á necessário Link to comment Share on other sites More sharing options...
pmg Posted August 3, 2012 at 08:46 AM Report Share #471353 Posted August 3, 2012 at 08:46 AM (edited) O teu problema é com o scanf(). Essa não é a função indicada para fazer o que pretendes. <parentesis> A função scanf (ou outras da mesma familia) pára quando o input não "servir" para o formato pedido. No teu caso, ao pedires um inteiro com "%d", mal o scanf veja uma letra pára. Se não encontrou nenhum número devolve 0 e deixa a variável num estado desconhecido. Por exemplo, se o input fosse "foo42" quando o scanf visse o 'f' parava e já não via o 'o', nem o "42". </parentesis> Tens de usar outra maneira de verificar se o input tem digitos. Sugestão: faz um ciclo para passar por todos os elementos do input e verifica se são dígitos ('0', '1', ..., '9'). -------- Sugestão #2: não uses o identificador string para as tuas variaveis. Tem dois inconvenientes: 1. É um identificador reservado, como todos os que começam por "str" e têm uma letra minuscula a seguir 2. É incompatível com C++ e com muitos "syntax highlighters" (incluindo o do P@P) Edited August 3, 2012 at 10:44 AM by pmg incompatibilidade com syntax highlighters What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código! Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted August 3, 2012 at 09:49 AM Report Share #471358 Posted August 3, 2012 at 09:49 AM (edited) lendo o enunciado à risca tem um problema ainda maior. nele (o enunciado) nada indica que a primeira linha é o número de linhas do ficheiro. para resolver o teu problema, digo-te já que o código final tem menos linhas das que apresentaste aqui. e como apresentaste uma tentativa de tentativa com pés e cabeça, onde se vê claramente que o problema é o desconhecimento dos pormenores do das funções do libc, vou te apresentar a minha solução: #include <stdlib.h> #include <stdio.h> #include <string.h> #define BUFFER_SIZE 256 int main() { FILE * input = NULL, * output = NULL; // ponteiros para os streams a usar char buffer[bUFFER_SIZE]; // buffer de leitura da linha do dficheiro ( > 200) int count = 0, i = 0; // contador e iterador de posição da linha /* abrir os ficheiros */ if ((input = fopen("texto.txt","r")) == NULL || (output = fopen("texto_digitos.txt","r")) == NULL) { perror("fopen"); exit(1); } /* ciclo de leitura do ficheiro de entrada */ while (fgets(buffer, BUFFER_SIZE, input)) { /* ciclo que verifica todos as caracteres da linha */ for (i = 0; i < (int)strrchr(buffer, '\n') - (int)buffer; i++) { /* verifica se o caracter é um digito */ if (buffer[i] >= '0' || buffer[i] <= '9') { /* inprimir a linha no ficheiro de saida, incrementar o contador e * sair do ciclo de verificação da linha */ fprintf(output, "%s", buffer); count++; break; } } /* limpar a linha do buffer para não haver problemas com a chamada * da função strrchr (nunca se sabe ) */ memset(buffer, 0, BUFFER_SIZE); } /* fechar os streams */ fclose(input); fclose(output); /* apresentar o numero de linhas copiadas */ printf("%d\n", count); return 0; } PS : isto foi tudo feito de cabeça, pode existir algum bugzito, mas sempre dá para tirares ideias Edited August 3, 2012 at 09:49 AM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
FrostPt Posted August 3, 2012 at 01:46 PM Author Report Share #471385 Posted August 3, 2012 at 01:46 PM (edited) Então pelo que percebi tudo o que esteja relacionado com scanf está fora de questão? Porque vai sempre parar, caso o input não seja um inteiro. Não percebi muito bem, o porquê de 'string' ser um identificador reservado, mas de qualquer das maneiras vou evitar usar, dessa forma. Quanto à primeira sugestão, já vi que a 'HappyHippyHippo' fez usando 'strrchr'. Admito que não sabia o que isso fazia :/ Pelo que deu a entender, nos sites que consultei, procura no buffer onde está o "\n", que corresponde ao final da string? Não percebi o que veio a seguir. Isto aqui - (int)buffer Nem porque é que o tamanho do buffer está a 256:SO resto também está bastante explícito, só não percebi o uso do memset :/ Acho que foi para iniciar a zero, para quando o 'strrchr' chamasse uma nova string do ficheiro texto.txt? Se fosse esse o caso, quando se chamasse, não substituia pelo que estava antes? Obrigado, por explicarem os meus erros, já estava a stressar todo porque não lia os números do ficheiro (ainda não lê, mas já estou mais perto de conseguir meter a funcionar ^^) Ah e pelas sugestões, vão ser úteis no futuro 😛 Edited August 3, 2012 at 01:59 PM by FrostPt Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted August 3, 2012 at 02:06 PM Report Share #471389 Posted August 3, 2012 at 02:06 PM ok ... vamo slá por partes então - o que o @pmg disse sobre a palavra reservada "string" é relevante ao C++. na realidade não é uma palavra reservada mas sim um identificador pré-definido da STL. o que acontece quando tentares utiliza código C++ é que ao definires que estás a usar a biblioteca STL: #include <string> using namespace std; a palavra "string" já se encontra definida o que irá causar colisão de definições. - a função strrchr retorna o ponteiro para a última ocorrência do caracter X na string dada. - é normal não teres percebido bem o (int)strrchr(buffer, '\n') - (int)buffer isto porque estás a começar , mas vou tentar explicar. buffer e strrchr são ponteiros/arrays, logo o seu valor é um número que representa a posição de memória onde se encontra os dados. como os dados do array são caracteres o seu tamanho/espaço de memória é 1 byte, logo a diferença das duas posições dá diretamente o número de caracteres/bytes entre a primeira posição (buffer) e a posição da última ocorrência do caracter '\n' (strrchr). claro que podias usar strlen(buffer) que daria o mesmo resultado, mas foi um desvaneio meu para tentar ver se percebias o que estava escrito. - o uso do memset é para "limpar" o buffer e fazer com que todos os caracteres deste tomem o valor de '\0' (que é o valor de termino da string). É certo que a especificação do fgets dita que o caracter '\0' é adicionado no fim da leitura, mas já diz o ditado : "fiar nem na virgem maria". Agora porque forçar a existência do '\0'. Imagina que a segunda string lida é menor que a primeira. Se o fgets não colocar o caracter '\0' no final estás gravar a segunda string no início da primeira ficando com uma salgalhada tremenda. IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
FrostPt Posted August 3, 2012 at 02:40 PM Author Report Share #471393 Posted August 3, 2012 at 02:40 PM (edited) Ok, já percebi melhor aquela parte relacionada com o identificador pré-definido 'string'. Isso significa que em C não causa problemas, mas se for em C++ já se chateia. Bem, vou evitar usá-la para esses fins, assim ninguém tem problemas xD A parte do memset também já entendi, era mais ou menos o que tinha em mente, está relacionado um bocado com organização e estética do programa 😄 Agora, estou a tentar digerir a função 'strrchr' xD Hmmm isso significa que vai a posição de memória onde começa o array e a posição onde acaba? Sendo a diferença o tamanho total da string? Daí teres dito que o strlen ia dar ao mesmo? Mas o strrchr não dá um char ou uma coisa do género, enquanto o strlen dá um inteiro? Algo assim: strrchr("Hello world!","world"); world! a = 'abcdef'; strlen (a); /* Que dá 6 */ Não sei se me fiz entender :/ Edited August 3, 2012 at 02:41 PM by FrostPt Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted August 3, 2012 at 02:53 PM Report Share #471394 Posted August 3, 2012 at 02:53 PM Ok, já percebi melhor aquela parte relacionada com o identificador pré-definido 'string'. Isso significa que em C não causa problemas, mas se for em C++ já se chateia. Bem, vou evitar usá-la para esses fins, assim ninguém tem problemas xD fazes bem A parte do memset também já entendi, era mais ou menos o que tinha em mente, está relacionado um bocado com organização e estética do programa 😄 em programação a única coisa que tem haver com estética é a indentação, todo o resto é funcional ... Agora, estou a tentar digerir a função 'strrchr' xD Hmmm isso significa que vai a posição de memória onde começa o array e a posição onde acaba? Sendo a diferença o tamanho total da string? Daí teres dito que o strlen ia dar ao mesmo? epa ... a tamanho é dado pela diferença entre as duas posições ... foi isso que escrevi ... já estás a inventar. volta a ler o que escrevi mas com calma. IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
FrostPt Posted August 3, 2012 at 03:48 PM Author Report Share #471396 Posted August 3, 2012 at 03:48 PM Bem, fiz com strlen funcionou às mil maravilhas ^^ Obrigado, pela ajuda e explicações 😄 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now