Jump to content

Duvida com ficheiros


einstein
 Share

Recommended Posts

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);
}
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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);
  }
}
Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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 ?

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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

Link to comment
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
 Share

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