Jump to content
Sign in to follow this  
einstein

Duvida com ficheiros

Recommended Posts

einstein

Pretendo implementar um programa que leia do teclado o nome do ficheiro que vai escrever se esse nome for stdout ele escreve no ecra. O que o programa tem que escrever e a tabuada do 1 ao 10. O código que eu fiz foi o seguinte:

Só que o programa quando eu escrevo stdout ele nao escreve no ecra e quando escreve no ficheiro apenas escreve a tabuado do 1

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

#define BUFFSIZE 1024

int main () {
FILE	 *fp;
char nome_fich[bUFFSIZE];
int i=1;
int p=1;

printf("Introduza o nome do ficheiro\n");
fgets(nome_fich, BUFFSIZE, stdin);

if (strcmp(nome_fich,"stdout")==0){
	while(p<=10){
		while(i<=10){
			printf("%d * %d = %d \n",p,i,p*i);
			i++;
		}
		p++;
	}
}else {

	fp=fopen(nome_fich,"w");
	if (fp==NULL){
		printf("Ficheiro inexistente");
		exit(-1);
	}
	else{
		while(p<=10){
			while(i<=10){
				fprintf(fp,"%d * %d = %d \n",p,i,p*i);
				i++;
			}
			p++;
		}		
	}fclose(fp);
}
exit(0);
}

Share this post


Link to post
Share on other sites
KiNgPiTo

O fgets inclui o \n no final da string, podes fazer um fix algo deste género se quiseres usar o fgets:

        fgets(nome_fich, BUFFSIZE, stdin);
        char *straux = strchr(nome_fich, '\n');
if (straux) *straux = '\0';

E acho que só está a fazer a tabuada do 1 pois quando o p incrementa a 1ª vez o i está a 11 logo nunca entra no ciclo interno... quando fazes p++; acrescenta aí i=1;

Cumprimentos

Share this post


Link to post
Share on other sites
bsccara

Para ignorares o '\n' final usa a função 'strncmp'  em vez de 'strcmp':

if (strncmp(nome_fich,"stdout",sizeof("stdout"))==0){

Em vez do sizeof podes meter o tamanho em bytes da string "stdout" à mão mas assim o código não funcionará em DBCS ou Unicode.

Em ambos os casos (stdout ou ficheiro) apenas mostras a tabuada de 1 porque não reinicializas a variável 'i' a 1. Logo o ciclo interior só executa uma vez.

Para este efeito deves usar o ciclo 'for'; não só é mais simples como evita estes esquecimentos.

for (p=1; p<=10; p++){
  for(i=1; i<=10; i++){
    printf("%d * %d = %d \n",p,i,p*i);
  }
}

Share this post


Link to post
Share on other sites
pmg

Para ignorares o '\n' final usa a função 'strncmp'  em vez de 'strcmp':

if (strncmp(nome_fich,"stdout",sizeof("stdout"))==0){

Acho que querias dizer strlen() em vez do sizeof ...

sizeof "stdout" é 7; strlen("stdout") é 6


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!

Share this post


Link to post
Share on other sites
pmg

Pretendo implementar um programa que leia do teclado o nome do ficheiro que vai escrever se esse nome for stdout ele escreve no ecra.

Podes atribuir stdout à variável fp, e, dependendo do que o utilizador escrever, abrir (e fechar) o ficheiro pedido

FILE *fp = stdout;
if (<SOMETHING>) {
    fp = fopen(...);
}

fprintf(fp, ...); // print para o ficheiro ou para stdout

if (<SOMETHING>) {
    fclose(fp);
}


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!

Share this post


Link to post
Share on other sites
bsccara

Acho que querias dizer strlen() em vez do sizeof ...

Não, o meu raciocínio era outro mas estava errado. A ideia era evitar explicitamente o 'strlen' porque essa função retorna o nº de bytes da string e não necessariamente o nº de caracteres. Mas como a função 'strncmp' compara byte a byte o parâmetro de tamanho deve mesmo ser em bytes. De qualquer maneira para strings em Unicode deve-se usar a função 'wcsncmp' para compará-las e a função 'wcslen' para medi-las. Enfim, uma trapalhada...

Share this post


Link to post
Share on other sites
einstein

Podes atribuir stdout à variável fp, e, dependendo do que o utilizador escrever, abrir (e fechar) o ficheiro pedido

FILE *fp = stdout;
if (<SOMETHING>) {
    fp = fopen(...);
}

fprintf(fp, ...); // print para o ficheiro ou para stdout

if (<SOMETHING>) {
    fclose(fp);
}

Obrigado a todos pela ajuda. Realmente estava a esquecer-me de voltar a inicializar o i. Bsccara com ciclos for fica mais simples, nem me tinha lembrado.

pmg nao percebi foi a tua solução :S . O nome do ficheiro tem que ser lido do teclado . No inicio com essa inicialização estas a fazer o que ?

Share this post


Link to post
Share on other sites
pmg

pmg nao percebi foi a tua solução :S . O nome do ficheiro tem que ser lido do teclado . No inicio com essa inicialização estas a fazer o que ?

O stdout é uma expressao de tipo FILE*. Podes usar stdout em qualquer sitio onde usarias outro "ficheiro".

O que eu fiz foi copiar esse valor para outra variavel. Depois, consoante o utilizador escrever "stdout" ou nao, mudo esta outra variavel ou nao. No fim deste processo, a variavel fp ou "aponta" para um ficheiro escolhido pelo utilizador ou "aponta" para stdout.


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!

Share this post


Link to post
Share on other sites
einstein

O stdout é uma expressao de tipo FILE*. Podes usar stdout em qualquer sitio onde usarias outro "ficheiro".

O que eu fiz foi copiar esse valor para outra variavel. Depois, consoante o utilizador escrever "stdout" ou nao, mudo esta outra variavel ou nao. No fim deste processo, a variavel fp ou "aponta" para um ficheiro escolhido pelo utilizador ou "aponta" para stdout.

Se o utilizador escrever stdout no 1º if naquele fopen o que vou colocar?

Share this post


Link to post
Share on other sites
pmg
FILE *fp = stdout;
int mustclose = 0;
char filename[1000];
size_t filenamelen;

/* ... */
if (fgets(filename, sizeof filename, stdin)) {
    if (strcmp(filename, "stdout\n") != 0) {
        filenamelen = strlen(filename);
        if (filename[filenamelen - 1] == '\n') filename[--filenamelen] = 0; // limpar '\n'
        else /* error: input too long */;
        fp = fopen(filename, "w");
        if (!fp) /* error */;
        mustclose = 1;
    }
} else /* error */;

fprintf(fp, "hello world\n"); // print to specific file or to stdout
/* ... */

if (mustclose) {
    fclose(fp);
}


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!

Share this post


Link to post
Share on other sites
einstein

FILE *fp = stdout;
int mustclose = 0;
char filename[1000];
size_t filenamelen;

/* ... */
if (fgets(filename, sizeof filename, stdin)) {
    if (strcmp(filename, "stdout\n") != 0) {
        filenamelen = strlen(filename);
        if (filename[filenamelen - 1] == '\n') filename[--filenamelen] = 0; // limpar '\n'
        else /* error: input too long */;
        fp = fopen(filename, "w");
        if (!fp) /* error */;
        mustclose = 1;
    }
} else /* error */;

fprintf(fp, "hello world\n"); // print to specific file or to stdout
/* ... */

if (mustclose) {
    fclose(fp);
}

ok. Já percebi obrigado

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.