[c++] fopen e fprintf

valentino861
Ho un problema con queste funzioni della libreria standard.

fopen() : sto cercando di fargli aprire ogni volta un file diverso ma non so come, cioè ho un programma che ogni tot secondi richiama una funzione che include fopen(), quindi apre un file e ci mette dei dati. E' possibile cambiare ogni volta in automatico il file che apre per fargli scrivere su un file diverso?

fprintf() : è possibile limitare il numero di cifre significative di una variabile double che devo scrivere su un file? Praticamente io faccio prima una scritta con le intestazioni delle colonne, e poi il programma mi entra in un ciclo for, e ogni ciclo usa fprintf() per scrivere delle righe di dati rispettivamente sotto ogni colonna. Il problema è che non riuscendo a controllare il numero di cifre significative non riesco a fare delle colonne ordinate.

Risposte
apatriarca
Per quanto riguarda fopen è sufficiente passargli ogni volta un nome di file differente. Ricordati però di chiudere tutti i file alla fine dell'uso con fclose.

Per fprintf è sufficiente scrivere il seguente:

fprintf(fout, "%.5f", numero_double);

oppure se il numero di cifre dopo la virgola lo vuoi passare come argomento alla funzione e non scrivere nella stringa:

fprintf(fout, "%.*f", numero_cifre, numero_double);

valentino861
ok per fprintf mi sembra ok. Per fopen il problema è che sta all'interno di un ciclo for. Cioè non posso passargli io ogni volta un nome diverso, dovrebbe essere lui a cambiarlo ogni volta che riprende viene richiamata quella funzione.

valentino861
aaaa ma posso anche inserire una stringa

http://www.pierotofy.it/pages/extras/fo ... per_fopen/

allora è facilissimo, ogni volta che entra nella funzione gli faccio cambiare nome

apatriarca
Non c'è modo di dire a fopen di aprire ogni volta dei file diversi. Non vedo perché non puoi editare ogni volta il nome della stringa del file prima di chiamare fopen anche se è all'interno di un ciclo. Esistono comunque due soluzioni standard (nel senso che sono funzioni definite in stdio.h):
1. Usare tmpfile() che apre un file temporaneo. Questo file viene cancellato alla fine della tua applicazione (o quando viene chiuso) e quindi potrebbe non essere una soluzione se hai bisogno di mantenere i file.
2. Usare tmpnam per ottenere un nome casuale valido e poi passare questa stringa a fopen.

valentino861
nel link che ho messo passa a fopen una cariabile char contenente il nome del file da salvare...è sbagliata?

apatriarca
Scusa... non avevo letto il tuo post precedente e quindi non avevo visto. Devi passare ad fopen una variabile di tipo char* contenente il nome del file. Come facevi prima? Ovviamente puoi anche usare la classe string per semplificarti la vita.

valentino861
prima semplicemente scrivevo la path del file tipo:

FILE* prova;
prova=fopen("C:\\prova.dat","w");


Ora invece potre per esempio fare un cosa del genere:

FILE* prova;

for(int i=0;i<3;i++){

string a="C:\\prova"+i+".dat";
prova=fopen(a,"w");
fprintf(prova,"Questo è il file %s",a);
}
fclose(prova)


Giusto??Quindi mi apre tre file diversi

valentino861
ho problemi qui non mi gira

string a="C:\\prova"+i+".dat";

apatriarca
L'operatore + di string è fatto per concatenare stringhe e non permette quindi di passare un un numero intero come parametro.

Un metodo abbastanza semplice per fare quello che desideri è l'uso di sprintf. Si tratta di una funzione in stdio.h che stampa su stringa. Non verifica i limiti dell'array e quindi è tuo compito essere certo che questo non avvenga, ma in questo caso è abbastanza semplice. La microsoft ha creato di alcune funzioni come questa una versione più sicura che dovrebbe chiamarsi sprintf_s. Non è però molto portabile anche se in futuro verrà probabilmente aggiunta allo standard. Il seguente codice visualizza ad ogni ciclo stringhe diverse:
#include <stdio.h>

int main()
{
    char str[30];
    int i = 0;

    for (; i < 10; ++i) {
        sprintf(str, "prova_%d.txt", i);
        puts(str);
    }

    return 0;
}


Un'altro metodo consiste nell'uso delle classi contenute in (questa funziona solo in C++). Questo è il codice equivalente a quello precedente:
#include <iostream>
#include <sstream>

int main()
{
    std::ostringstream sout;

    for (int i = 0; i < 10; ++i) {
        sout.str("");
        sout << "prova_" << i << ".txt";
        std::cout << sout.str() << std::endl;
    }
}

Nel codice ti ho anche mostrato le classi per l'I/O che fornisce il C++ oltre a quelle del C. Per scrivere su file è per esempio anche possibile usare le classi in che funzionano più o meno come quelle in questo pezzo di codice.

valentino861
ok, infatti anche su oltri forum mi hanno consigliato l'utilizzo di fstream se sto in c++.
Però sinceramente con la fprintf ho la possibilità di regolare molte cose che non posso con fstream.
Tipo quando immetto i dati non posso deciderne la lunghezza, la precisione ecc ecc.

apatriarca
In realtà puoi farlo. Il metodo per cambiare il numero di cifre dovrebbe chiamarsi precision, puoi anche cambiarlo all'interno dei << usando set_precision. Comunque per certe cose preferisco anche io le librerie del C (per esempio nell'esempio precedente).

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.