LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-21-2011, 10:37 AM   #1
robertodb
LQ Newbie
 
Registered: Sep 2011
Posts: 13

Rep: Reputation: Disabled
Unhappy fprintf problem (ofstream)


I wrote a program that creates a text file with some letters using ofstream. Now I would like to format the text so that the letters are written in groups of 5 and the rows are all the same length( i.e. LINUXQUESTIONS becomes LINUX QUEST IONS). To do this the fprintf function seemed the most appropriate. in the following example I use integers, but it is just an example.

Code:
#include <string>
#include <iomanip>
#include <fstream>
#include <cstdio>

using namespace std;

int main()
{
    ofstream f;
    
    f.open("testo.txt");
    
    for(int i = 0; i < 21; i++)
    {
            f << i;  
            }
            
    f.close(); //to simulate file already created
    
    FILE *file;
    int number;
    file = fopen("testo.txt", "r+");
    if (file==NULL) perror ("Error opening file");
    else
    {
        do {
           number = fgetc (file);
           fprintf(file, "%-5.5i", number);
        } while (number != EOF);
     }
     fclose(file);
     return 0;
}
can this method work? or there is some function that I can use directly when creating the file with ofstream?
please help
 
Old 09-21-2011, 10:53 AM   #2
Snark1994
Senior Member
 
Registered: Sep 2010
Distribution: Debian
Posts: 1,632
Blog Entries: 3

Rep: Reputation: 346Reputation: 346Reputation: 346Reputation: 346
Forgive me if I'm being foolish, but when you say

Quote:
or is there some function that I can use directly when creating the file with ofstream?
surely you could just write five characters, write a space, write another five, and so on until you run out of characters? That would be far easier than messing with the file after it's been created. The code you have there doesn't work (as you hopefully know); if you did want your approach to work, you'd have to use a temporary file (you're currently doing weird things by reading and writing) and you would again count five characters and then add a space, rather than playing with padding integers...

In the vein of the first suggestion, the following works:

Code:
#include <string>
#include <iomanip>
#include <fstream>
#include <cstdio>

using namespace std;

int main() {
    //Your code:
    ofstream f;
    
    f.open("testo.txt");
    
    for(int i = 0; i < 21; i++) {
                f << i;  
        }
            
    f.close(); //to simulate file already created
    
    //My code:
    FILE *in;
    FILE *out;
    in = fopen("testo.txt", "r");
    out = fopen("out.txt", "w");
    if (in==NULL) {
        perror ("Error opening file");
    } else {
        char character;
        do {
            for(int i=0;i<5 && character != EOF;i++){
                character = fgetc (in);
                fprintf(out, "%c", character);
            }
            fprintf(out, " ");
        } while (character != EOF);
     }
     fclose(in);
     fclose(out);
     return 0;
}
I used C-style file input/output because you did (though not for the first bit?), but it would be "better" to use C++ style I/O if you're using C++ (which you are if you're using string)

Hope this helps,

Last edited by Snark1994; 09-21-2011 at 10:55 AM. Reason: Strange indentations...
 
1 members found this post helpful.
Old 09-21-2011, 11:20 AM   #3
robertodb
LQ Newbie
 
Registered: Sep 2011
Posts: 13

Original Poster
Rep: Reputation: Disabled
Quote:
surely you could just write five characters, write a space, write another five, and so on until you run out of characters? That would be far easier than messing with the file after it's been created.
this is the piece of original code
Code:
void Vigenere::encode(string plaintext, string encoded_f){
       ofstream f; 
                     
       TextErase();
       LoadText(plaintext); //load a text file in text (vector<string>)
       
       f.open(encoded_f.c_str());
       if(!f.is_open()){
           cout << "Error creating file: " << encoded_f << " !" << endl;
           return;
       }
       
       int* index_k = new int[key.length()]; //key indexs array
       for(int i = 0; i < key.length(); i++){
               for(int j = 0; j < 21; j++){
                       if(key[i] == ALPH[j])
                       index_k[i] = j;
               }
       }
       
       int passcnt = 0;
       for(int i = 0; i < text.size(); i++){ 
               for(int j = 0; j < text[i].size(); j++){ 
                    int* index_t = new int[text[i].length()];
                         for(int k = 0; k < 21; k++){ 
                              if(text[i][j] == ALPH[k])
                              index_t[j] = k;
                         }
                    char ch = ALPH[(index_t[j] + index_k[passcnt])%21];
                    f << ch;
                    passcnt++;
                    if(passcnt > (key.length() - 1))
                    passcnt = 0;
                    
                    delete[] index_t; 
               }
               f << "\n";
       }
       f.close();
       delete[] index_k;
       return;
}
how can I change this to do what you say? by the way, you're completely right, this way seems to be easier, but after a day spent at the computer, the brain no longer works well...

Last edited by robertodb; 09-21-2011 at 11:21 AM.
 
Old 09-21-2011, 05:06 PM   #4
Snark1994
Senior Member
 
Registered: Sep 2010
Distribution: Debian
Posts: 1,632
Blog Entries: 3

Rep: Reputation: 346Reputation: 346Reputation: 346Reputation: 346
I will admit to being both rather tired and in a state of mild intoxication, so I will have another look at it tomorrow... However, it looks like if you change it to:

Code:
void Vigenere::encode(string plaintext, string encoded_f){
//     ...
       int numberOfCharsPrinted = 0;
       
       int passcnt = 0;
       for(int i = 0; i < text.size(); i++){ 
               for(int j = 0; j < text[i].size(); j++){ 
//      ...
                    char ch = ALPH[(index_t[j] + index_k[passcnt])%21];
                    if (numberOfCharsPrinted == 5){
                        f << ' ';
                        numberOfCharsPrinted = 0;
                    }
                    f << ch;
                    passcnt++;
                    numberOfCharsPrinted++;
//      ...
       return;
}
...where "..." represents code which should be included but which I've omitted to make the changes that I've made more clear

Hope this helps,
 
1 members found this post helpful.
Old 09-22-2011, 02:08 AM   #5
robertodb
LQ Newbie
 
Registered: Sep 2011
Posts: 13

Original Poster
Rep: Reputation: Disabled
thank you very much. I can't believe...it works!!!
 
Old 09-22-2011, 02:44 AM   #6
robertodb
LQ Newbie
 
Registered: Sep 2011
Posts: 13

Original Poster
Rep: Reputation: Disabled
ok it works, but there's something I can't understand in the output. the content of a text file is
Code:
roberto di bernardo
file di testo
prova criptografica
and, after encoding, the output file is
Code:
LDCIL PDUZC ILHOL RP
LCF SUZUI MPD
HG PCRVG CEUSA NOZZD E
while I'd like to have something like this
Code:
LDCIL PDUZC ILHOL RP
LCFSU ZUIMP D
HGPCR VGCEU SANOZ ZDE
how can I fix that? I swear, this will be the last question...I'll not bother you anymore, at least for the next two or three weeks.
 
Old 09-22-2011, 08:36 AM   #7
Snark1994
Senior Member
 
Registered: Sep 2010
Distribution: Debian
Posts: 1,632
Blog Entries: 3

Rep: Reputation: 346Reputation: 346Reputation: 346Reputation: 346
Right, all you need to do is put another "numberOfCharsPrinted = 0;" after "f << '\n';"; if you look at your output it is putting a space after every 5 characters, but sometimes the linebreak occurs in the middle. Setting numberOfCharsPrinted to 0 after every linebreak means everything will come out in groups of 5.

Don't worry about asking questions, it is a real pleasure to be able to help someone, especially someone who's polite

Buona fortuna!
 
1 members found this post helpful.
Old 09-22-2011, 09:23 AM   #8
robertodb
LQ Newbie
 
Registered: Sep 2011
Posts: 13

Original Poster
Rep: Reputation: Disabled
ok, now it's perfect, just like I wanted.
grazie
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
GCC 4.1.2 ofstream problem SJD Programming 10 11-14-2008 07:57 AM
ofstream & ifstream simple (i think) problem nadroj Programming 2 04-25-2006 10:28 PM
ofstream and inheritence phoenix7 Programming 1 01-02-2005 02:52 AM
ofstream problem cgifalcon Linux - Software 2 10-19-2003 12:00 PM
c++ ofstream -> FILE * ChimpFace9000 Programming 1 08-25-2002 04:58 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:02 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration