2010-07-19 5 views
1

J'essaie d'écrire le contenu du pointeur buf dans le fichier créé par ofstream.ofstream n'écrit pas le tampon dans le fichier

Pour une raison quelconque, le fichier est vide, mais le contenu de buf n'est jamais vide ... Qu'est-ce que je fais mal?

void DLog::Log(const char *fmt, ...) 
{ 
    va_list varptr; 

    va_start(varptr, fmt); 

    int n = ::_vscprintf(fmt, varptr); 
    char *buf = new char[n + 1]; 
    ::vsprintf(buf, fmt, varptr); 

    va_end(varptr); 

    if (!m_filename.empty()) 
    { 

     std::ofstream ofstr(m_filename.c_str(), ios::out); 

     ofstr << *buf; // contents of *buf are NEVER empty, however nothing is in file?? 

     ofstr.close(); 
    } 


    delete [] buf; 
} 
+1

Je pense que nous aurions besoin de voir le code d'appel aussi, peut-être vous pouvez le réduire à un exemple compilable? Aussi, n'utilisez pas l'allocation manuelle comme ça. :) Changez votre substance 'buf' en' std :: vector buf (n + 1); 'et' :: vsprintf (& buf [0], fmt, varptr); 'et pour la sortie,' std :: copy (buf.begin(), buf.end(), std :: ostream_iterator (ofstr)) '. Et bien sûr, pas besoin de "supprimer []" plus. De plus, vous n'avez pas besoin d'appeler 'ofstr.close() ', le destructeur le fait de toute façon. – GManNickG

+0

avez-vous vérifié les autorisations sur le fichier journal? – CharlesB

+0

@GMan: 'std :: string' ne correspondrait-il pas plus que nécessaire à' std :: vector '? – ereOn

Répondre

3

De nombreux problèmes peuvent être résolus en se débarrassant des trucs poilus, comme la gestion manuelle de l'allocation. N'utilisez jamais new T[N] dans votre code: utilisez plutôt std::vector<T> v(N);. Il suffit de cela seul peut résoudre votre problème, parce que les choses pointeur n'est pas la manière:

void DLog::Log(const char *fmt, ...) 
{ 
    va_list varptr; 
    va_start(varptr, fmt); 

    int n = ::_vscprintf(fmt, varptr); 
    std::vector<char> buf(n + 1); 

    ::vsprintf(&buf[0], fmt, varptr); 

    va_end(varptr); 

    if (!m_filename.empty()) 
    { 
     std::ofstream ofstr(m_filename.c_str(), ios::out); 
     if (!ofstr) 
     { 
      // didn't open, do some error reporting here 
     } 

     // copy each character to the stream 
     std::copy(buf.begin(), buf.end(), std::ostream_iterator<char>(ofstr)); 

     // no need to close, it's done automatically 
    } 

    // no need to remember to delete 
} 

beaucoup plus facile à lire et à maintenir. Notez encore mieux serait un std::string buf(n + 1);, alors vous pouvez simplement faire ofstr << buf;. Malheureusement, std::string n'est actuellement pas nécessaire pour stocker ses éléments de manière contiguë, comme std::vector. Cela signifie que la ligne avec &buf[0] n'est pas garantie de fonctionner. Cela dit, je doute que vous trouverez une implémentation où cela ne fonctionnerait pas. Pourtant, il est sans doute préférable de maintenir un comportement garanti.

Je fais suspect le issue étiez-vous déréférencer le pointeur, cependant.

0

Vous devez vérifier que l'ofstream est ouvert pour l'écriture après sa création.

4

Votre flux est-il ouvert avant d'écrire dessus? Peut-être quelque chose de pas assez d'espace disque à des autorisations insuffisantes.

Aussi, vous pouvez avoir une erreur:

ofstr << *buf; 

devrait être quelque chose comme:

ofstr << buf; 

Depuis buf est un char*, *buf donne un char, pas char*.

Ceci est où std::string en utilisant à la place des tampons/pointeurs premières est logique;)

1

l'erreur se trouve dans la ligne

ofstr < < * buf;

il devrait être

ofstr < < buf;

2

Vous devez vider le ofstream avant de le fermer. Essayez ofstr.flush(); avant ofstr.close(); J'ai eu cette erreur il y a quelque temps quand j'ai pensé que la fermeture du flux le vidait automatiquement mais, comme il s'est avéré, ce n'est pas le cas.

+0

Je suis assez sûr qu'il devrait, peut-être que c'était un bug dans votre mise en œuvre. Mais peut-être que je me trompe, je vais regarder – GManNickG

+0

@GMan: Avez-vous regardé? Dites-nous si vous trouvez quelque chose d'intéressant – binW

+0

Ah, oui, c'est en effet le cas 'close()' vide le flux, et que 'close()' est appelé par le destructeur §27.8.1.2/3 décrit le destructeur d'un 'basic_filebuf', et dit qu'il appelle' close() '. §27.8. Les flux de fichiers ont tous le même comportement que celui de posséder un basic_filebuf en tant que membre, ce qui signifie qu'ils détruisent le fichier basic_filebuf, ce qui conduit aux effets précédents. – GManNickG

Questions connexes