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. DANIWEBFORUM becomes DANIW EBFOR UM). 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;

}

[/CODE]
can this method work? or there is some function that I can use directly when creating the file with ofstream?
please help

of course this is only a piece a code, the part which doesn't work. do you want me to post the entire code? actually, I'd have written: let's suppose you have already opened a text file and stored it in the list.
the main problem is the for loop: what I'm trying to do is compare the key with ALPH to find matches, and if so update the index variable, same thing for the list. So I have to read every character of every string of the list, do something and then write results on a text file.
Can you tell me how to adjust the for loop? I do not necessarily use iterators, it was just an idea, if there is more to solve the problem should be okay.

I've created a list of strings and load a text file in it. once list is created, the program have to read it, do something and write results in a new text file.

[CODE]
ofstream f;
f.open("filename.txt");

string key;
list<string> text;
static char ALPH[21] = {'A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R','S','T','U','V','Z'};

int index_t = new int[text.size()];
int
index_k = new int[key.length()];

for(int i = 0; i < key.length(); i++){
for(int j = 0; j < 21; j++){
if(key[i] == ALPH[j])
index_k[i] = j;
}
}

for(list<string>::iterator it = text.begin(); it != text.end(); it++){
for(int i = 0; i < it->length(); i++){
for(int j = 0; j < 21; j++){
if((*it)[i] == ALPH[j])
index_t[i] = j;
}
char ch = ALPH[(index_k[i%key.length()] + index_t[i])%21];
f << ch;
}
f << "\n";
}

    f.close();

[/CODE]
I have not even tried to implement it because I already believe is wrong. someone tell me how to change it to be able to make it work?
thank you :confused:

I've tried to use strchr as you suggested, but it doesn't work. here's the complete code, maybe it could be helpful

[CODE]
//vigenere algorithm with Italian alphabet

include <string>
include <iostream>
include <fstream>
include <vector>
include <string.h>

using namespace std;

class Vigenere
{
public:
string key;
vector<string> text;

Vigenere(string str){
   key = str;
   key = StringToUpper(key);
   if(!key.empty()){
       key = EraseChar(key);
   }

   return;
}

//converts every letter to uppercase
string StringToUpper(string convstr){
   for(int i = 0; i < convstr.length(); i++){
           convstr[i] = toupper(convstr[i]);
           }
   return convstr;
}

//load the content of a file into text
void Vigenere::LoadText(string filename){
       ifstream f; 
       string line;

       f.open(filename.c_str()); 
       if(!f.is_open()){
            cout << "Error opening file: " << filename << " !" << endl;
            return;
       }

       while(getline(f,line)){
            line = StringToUpper(line);
            if(!line.empty()){
               line = EraseChar(line);
               text.push_back(line);
            }               
       }

      f.close();
}

//deletes all characters not in ALPH
string EraseChar(string str){
   char ALPH[21] = {'A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R','S','T','U','V','Z'};
   str = StringToUpper(str);
   for(int i = 0; i < str.length(); i++){
   bool inAlph = false;
        for(int j = 0; j < 21; j++){
                if(str[i] == ALPH[j]){
                inAlph = true;
                break; // don't need to keep checking against the rest of ALPH
                }
        }
        if (!inAlph) {
        str.erase(i,1);
        i--;
        }
   }
   return str;
}

void encode(string plaintext, string encoded_f){
   ofstream f; 
   char ALPH[21] = {'A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R','S','T','U','V','Z'};

   TextErase();
   LoadText(plaintext); 

   f.open(encoded_f.c_str());
   if(!f.is_open()){
       cout << "Error creating file: " << encoded_f << " !" << endl;
       return;
   }

/****************************************************************************
* each letter in ALPH is associated with an index, so A-->0 B-->1 and so on.
* now it checks every characters ...

I will be more clear: I have to compare each character of each string in vector. If the comparison is positive, I associate the array index corresponding to the letter to a variable. For example, if the character of a string in vector is 'R', the index variable assumes a value of 15, as ARRAY [15] = R.

I have to write an application in which a text file is read and stored in a vector of strings
[CODE]vector<string> text;[/CODE]
After that I have to compare each character of text loaded from a file with an array of char with default content
[CODE]char ARRAY[21] = {... ... ...}[/CODE]
so I thought something like that
[CODE]
for(int i = 0; i < text.size(); i++){
for(int j = 0; j < 21; j++){
if(text[i] == ARRAY[j])
index_t[i] = j;
}
}
[/CODE]

at compile time I get the following error:
no match for 'operator==' in '(((std::vector<std::string, std::allocator<std::string> >*)
how can I fix that?

if I use new to dinamically allocate an array, can I solve the problem?

the program must read a text file, encrypt the content and then rewrite everything to a text file. compile ok, it crashes while running and still produces an empty output. how can I fix this?

vigenere.h
[CODE]

include <string>

using namespace std;

class Vigenere{
private:
string key;
string text;
static char ALPH[21];

          static string StringToUpper(string);
          void LoadText(string);
          static string EraseChar(string);
          void TextErase();
  public:        
          Vigenere(string);
          void encode(string, string);
          void decode(string, string);

};
[/CODE]vigenere.cpp
[CODE]

include "vigenere.h"
include <string>
include <iostream>
include <fstream>

using namespace std;

//genera la chiave
Vigenere::Vigenere(string str){
key = str;
key = StringToUpper(key);
if(!key.empty()){
key = EraseChar(key);
}

   return;

}

//array con i caratteri dell'alfabeto italiano
char Vigenere::ALPH[21] = {'A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R','S','T','U','V','Z'};

//converte tutte le lettere in maiuscolo
string Vigenere::StringToUpper(string convstr){
for(int i = 0; i < convstr.length(); i++){
convstr[i] = toupper(convstr[i]);
}
return convstr;
}

//copia il contenuto di un file di testo nella stringa text
void Vigenere::LoadText(string filename){
ifstream f; //crea uno stream di input

   f.open(filename.c_str()); //apre il file specificato in filename e lo associa allo stream di input
   if(!f.is_open()){
        cout << "Errore nell'apertura del file: " << filename << " !" << endl;
        return;
   }

   while(!f.eof()){
        getline(f,text); //legge il contenuto del file e lo mette nella variabile text
        text = StringToUpper(text);
        if(!text.empty())
        text = EraseChar(text);
   }

  f.close();

}

//elimina i caratteri speciali, tenendo solo le lettere dell'alfabeto italiano (contenute in ALPH)
string Vigenere::EraseChar(string str){
str = StringToUpper(str);
for(int i = 0; i < str.length(); i++){
bool inAlph = false;
for(int j = 0; j < 21; j++){ ...

I'm trying to fix problems using debug-prints as you suggested me. So I've modified the function encode in this way
[CODE]
string encode(string text){
char ALPH[21] = {'A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R','S','T','U','V','Z'};
text = StringToUpper(text);
if(!text.empty()){
text = EraseChar(text);
}

   cout << "String text: " << text << endl;

   int index_k[key.length()];  //key's 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;
           }
   cout << "Index key " << i << ": " << index_k[i] << endl;                
   }

   int index_t[text.length()];  //text's indexs array
   for(int i = 0; i < text.length(); i++){
           for(int j = 0; j < 21; j++){
                   if(text[i] == ALPH[j])
                   index_t[i] = j;
           }
   cout << "Index text " << i << ": " << index_t[i] << endl;                
   }

   string line;
   //coded letter
   for(int i = 0; i < text.length(); i++){
           line[i] = ALPH[(index_k[i%key.length()] + index_t[i])%21];
           cout << "Coded Letter " << i << ": " << line[i] << endl;
   }

   return line;       
}

[/CODE]

and everything works, all coded letters are printed. So, what could be the problem? Why can't I visualize the output when I call the function in main?
:(

thank you very much, now it works. I think I only have one last problem :( with functions encode and decode.
when I write in main
[CODE]
string encrypted = cipher.encode(original);
string decrypted = cipher.decode(encrypted);

cout << "Encrypted: " << encrypted << endl;
cout << "Decrypted: " << decrypted << endl;
[/CODE]

nothing appears in the output

I've tried to modify the function following your advices. This is the result
[CODE]
string EraseChar(string str){
char ALPH[21] = {'A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R','S','T','U','V','Z'};

   str = StringToUpper(str);
   cout << "str = '" << str << "'" << endl;

   int match;

   for(int i = 0; i < str.length(); i++){
           for(int j = 0; j < 21; j++){
                   if(str[i] == ALPH[j]){
                   continue;  
                   match = 1;
                   }
                   else
                   match = 0;              
           }

           if(match == 1) continue;
           else if(match == 0)
           str.erase(i,1);               
   }
   cout << "str = '" << str << "'" << endl;
   return str;
}

[/CODE]

but now the function keeps only even letters. For example, the key is ROBERTO, the output is OET. the problem is...I can't find out a solution. :(

I've modified the erasechar function as you suggested. Now it deletes all characters not included in ALPH.
[CODE]
string Vigenere::EraseChar(string str){
for(int i = 0; i < str.length(); i++){
for(int j = 0; j < 21; j++){
if(str[i] != ALPH[j])
str.erase(i,1);
}
}
return string;
}
[/CODE]
but i can't visualize the output yet. Is there something wrong in main.cpp?

I've modified the code and now it seems to be correct. But I can't visualize the encoded string as well as the decoded one in the output. here's the code
[CODE]
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// vigenere.h
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

include <string>

using namespace std;

class Vigenere{
private:
string key;
static char ALPH[21];
static string StringToUpper(string);
static string EraseChar(string);
public:
Vigenere(string);
string encode(string);
string decode(string);
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// vigenere.cpp
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

include "vigenere.h"
include <string>

using namespace std;

Vigenere::Vigenere(string str){
key = str;
key = StringToUpper(key);
if(!key.empty()){
key = EraseChar(key);
}

   return;

}

char Vigenere::ALPH[21] = {'A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R','S','T','U','V','Z'};

//converts every letter to uppercase in the parameter convstr
string Vigenere::StringToUpper(string convstr){
for(int i = 0; i < convstr.length(); i++){
convstr[i] = toupper(convstr[i]);
}
return convstr;
}

//deletes the special characters, keeps only letters of the Italian alphabet
string Vigenere::EraseChar(string str){
for (int i = 0; i < str.length(); i++){
if(!(str[i] >= 'A' && str[i] <= 'Z'))
str.erase(i,1);
//i--;
}

   return str;

}

string Vigenere::encode(string text){
text = StringToUpper(text);
if(!text.empty()){
text = EraseChar(text);
}

   int index_k[key.length()];       //key's 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 index_t[text.length()];          //text's indexs array
   for(int i = 0; i < text.length(); i++){
           for(int j = 0; j < 21; j++){
                   if(text[i] == ALPH[j])
                   index_t[i] = j;
           }        
   }

   string line;
   //coded letter
   for(int i = 0; i < text.length(); i++){
           line[i] = ALPH[(index_k[i%key.length()] + index_t[i])%21];
   }

   return line;

}

string Vigenere::decode(string ...

I have to write an application which uses the Vigenere cipher with the Italian alphabet (only 21 characters, excluded J,K,W,X,Y). After a day of trying this is the code that I wrote

[CODE]

include "vigenere.h"
include <string>

using namespace std;

Vigenere::Vigenere(string str){
key = str;
key = StringToUpper(key);
for(int cnt = 0; cnt < key.length(); cnt++){
if(key[cnt] < 'A' || key[cnt] > 'Z')
key.erase(cnt,1);
}

                   //nel caso in cui la chiave sia piĆ¹ corta del testo
                   for(int cnt = 0; cnt < text.length(); cnt++){
                           if(key.length() != text.length()){
                                           if(key.length() < text.length())
                                           key += key[cnt];
                                           }                
                   }

                   return;

}

//tavola di Vigenere con alfabeto italiano
char Vigenere::Table(string alphabet){
int temp;
temp = alphabet.length();
int ROWS(temp);
int COLS(temp);
char ALPH[temp];
for(int i = 0; i < temp; i++){
ALPH[i] = alphabet[i];
}
char VIG[ROWS][COLS];

                   for(int i = 0; i < ROWS; i++){                              
                               for(int j = 0; j < COLS; j++){
                               VIG[i][j]=ALPH[(i + j)%21];
                               }
                    }
                    return VIG[ROWS][COLS];

}

string Vigenere::StringToUpper(string convstr){
for(int cnt = 0; cnt < convstr.length(); cnt++){
convstr[cnt] = toupper(convstr[cnt]);
}
return convstr;
}

//elimina i caratteri speciali, tenendo solo le lettere
string Vigenere::EraseChar(string str){
for (int i = 0; i < str.length(); i++){
if(!(str[i] >= 'A' && str[i] <= 'Z'))
str.erase(i,1);
i--;
}
return str;
}

string Vigenere::encode(string text){
string line;

   //cerca il valore corrispondente alla chiave nella prima colonna di VIG
   int index_k;
   for(int i = 0; i < ROWS; i++){ 
           if(key[i]==VIG[i][1])
           index_k = i;
   }

   //cerca il valore corrispondente al testo nella prima riga di VIG
   int index_t; ...

I've made only some ns2 scripts. Anyway, I know the vigenere cipher, but i don't understand how the algorithm works.

can someone tell me how this program works? I'm trying to learning C++ by reading some examples, and this one is one of them.
[CODE]#include <iostream>

include <string>

using namespace std;

class Vigenere
{
public:
string key;

Vigenere(string key)
{
for(int i = 0; i < key.size(); ++i)
{
if(key[i] >= 'A' && key[i] <= 'Z')
this->key += key[i];
else if(key[i] >= 'a' && key[i] <= 'z')
this->key += key[i] + 'A' - 'a';
}
}

string encrypt(string text)
{
string out;

for(int i = 0, j = 0; i < text.length(); ++i)
{
  char c = text[i];

  if(c >= 'a' && c <= 'z')
    c += 'A' - 'a';
  else if(c < 'A' || c > 'Z')
    continue;

  out += (c + key[j] - 2*'A') % 26 + 'A'; 
  j = (j + 1) % key.length();
}

return out;

}

string decrypt(string text)
{
string out;

for(int i = 0, j = 0; i < text.length(); ++i)
{
  char c = text[i];

  if(c >= 'a' && c <= 'z')
    c += 'A' - 'a';
  else if(c < 'A' || c > 'Z')
    continue;

  out += (c - key[j] + 26) % 26 + 'A'; 
  j = (j + 1) % key.length();
}

return out;

}
};

int main()
{
Vigenere cipher("VIGENERECIPHER");

string original = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
string encrypted = cipher.encrypt(original);
string decrypted = cipher.decrypt(encrypted);

cout << original << endl;
cout << "Encrypted: " << encrypted << endl;
cout ...

Anuradha Mandal commented: Not easy start. +0