0

I am having an issue getting extern to work properly or so I think.

What I want to do: I have a struct in a .h file that I am wanting to use in two seperate .cpp files. I do not want each .cpp file to have its own struct but rather one struct whose values are shared across both files.

This has led me to find "extern" from my understanding I can define a struct in my .h file and then declare that same struct in both .cpp files by adding the extern keyword in front of the declaration. To my understanding this shows the compiler that that variable or struct in this case is defined elsewhere... It sees the .h file included and goes and sees that is declared in my .h

In simple terms here is what I have.....

My .h file called project1.h

#ifndef PROJECT1_H
#define PROJECT1_H

struct proj{
char text[300];
char key[300];
char padded_key[300];
char vigenere_encrypted_text[300];
char vigenere_decrypted_text[300];
char affine_encrypted_text[300];
char affine_decrypted_text[300];
char two_block_ciphertext[300];
int mod;
char answer;
int multiplier;
int offset;
};

**proj lab1;**

#endif`#ifndef PROJECT1_H
#define PROJECT1_H

First .cpp file called v_encrypt.cpp

#include <iostream>
 #include <fstream>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include "project1.h"

 using namespace std;


 void ReadPlainText();
 void ReadVKey();
 void PadKey();
 void VigenereEncrypt();

 **extern proj lab1;**

 int main(){
   cout << "Are we using an all lowercase alphabet(modulo = 26, enter 'l' or both lowercase and uppercase(modulo = 52, 'u'))" << endl;
   cin >> lab1.answer;
   if(lab1.answer == 'l')
      lab1.mod = 26;
   else if(lab1.answer == 'u')
      lab1.mod = 52;
   else{
      cout << "Did not pick a correct choice for alphabet... exiting now..." << endl;
      exit;
   }

   cout << "Reading plain text from plaintext.txt" << endl;
   ReadPlainText();
   cout << "Plain Text: " << lab1.text << endl;

   cout << "Reading key for vigenere from vcipherkey.txt" << endl;
   ReadVKey();
   cout << "Key: " << lab1.key << endl;

   cout << "Padding key to match length of plain text so encryption can be performed properly" << endl;
   PadKey();
   cout << "Padded Key: " << lab1.padded_key << endl;

   cout << "Performing Vigenere Encryption on plain text now..." << endl;
   VigenereEncrypt();
   cout << "Vigenere Encrypted Text: " << lab1.vigenere_encrypted_text << endl;


   return 0;
 }

void ReadPlainText(){

  ifstream plain_text("plaintext.txt");
  int index = 0;
  if(!plain_text){
    cout << "Error could not open plain text file...perhaps it does not exist" << endl;
    exit;
  }
  while(!plain_text.eof()){
    plain_text >> lab1.text[index];
    index++;
  }
  plain_text.close();
}

void ReadVKey(){

  ifstream vkey("vcipherkey.txt");
  int index = 0;
  if(!vkey){
    cout << "Error could not open the file vcipherkey.txt perhaps it does not exist" << endl;
    exit;
  }
  while(!vkey.eof()){
    vkey >> lab1.key[index];
    index++;
  }

  vkey.close();
}

void PadKey(){
    int j = 0;
    for(int i = 0; i < strlen(lab1.text); i++){
        if(j == strlen(lab1.key)){
            //cout <<" HERE " << endl;
            j = 0;
        }

            //cout <<"key_array: " << key_array[j] << endl;
            lab1.padded_key[i] = lab1.key[j];
            //cout <<"padded_key_array["<<i<<"]: " << padded_key_array[i] << endl;
            j++;
    }

}

void VigenereEncrypt(){

    for(int i = 0; i < strlen(lab1.text); i++){
        lab1.vigenere_encrypted_text[i] = ((lab1.text[i] + lab1.padded_key[i]) % lab1.mod + 'A');
    }
    ofstream vigenere_cipher_text("vigenerecipheroutput.txt");
  cout << "Writing Vigenere Encrypted text to vigenerecipheroutput.txt" << endl;
    vigenere_cipher_text.write(lab1.vigenere_encrypted_text,strlen(lab1.vigenere_encrypted_text));
    vigenere_cipher_text.close();

}

2nd .cpp file called affine_encrypt.cpp

#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "project1.h"

using namespace std;

**extern proj lab1;**
void AffineEncrypt();

int main(){
  cout << "still have text ?: " << lab1.vigenere_encrypted_text << endl;
  cout << "Performing Affine Encryption now... " << endl;
  AffineEncrypt();
  cout << "Block Affine Encrypted text: " << lab1.affine_encrypted_text << endl;
  return 0;
}
void AffineEncrypt(){

  int j = 0;
  int k = 0;
  cout << "Dividing up the vigenere cipher text into blocks of two" << endl;
  for(int i = 0; i < strlen(lab1.vigenere_encrypted_text);i++){
      if(k==2){
          lab1.two_block_ciphertext[j] = ' ';
          k = 0;
          i--;
      }
      else{
          lab1.two_block_ciphertext[j] = lab1.vigenere_encrypted_text[i];
          k++;
      }
      j++;

  }
cout << "Padded Cipher text " << lab1.two_block_ciphertext << endl;
cout << "Enter the desired multiplier" << endl;
cin >> lab1.multiplier;
cout << "Enter the offset" << endl;
cin >> lab1.offset;
//int what=0;
for(int i = 0; i<strlen(lab1.two_block_ciphertext); i++){
  //what = (((multiplier * reading[i]) + offset) % 26);
      if((lab1.two_block_ciphertext[i]) == ' '){
          //cout << "Doing nothing on this "<< endl;
          lab1.affine_encrypted_text[i] = lab1.two_block_ciphertext[i];
      }
      else
          lab1.affine_encrypted_text[i] = (char )((((lab1.multiplier * lab1.two_block_ciphertext[i] - 'A') + lab1.offset) % 26) + 'A');
  //cout << "Value: " << what << endl;
}
ofstream affine_cipher_text("blockaffinecipheroutput.txt");
cout << "Writing Block affine encrypted text to blockaffinecipheroutput.txt" << endl;
affine_cipher_text.write(lab1.affine_encrypted_text,strlen(lab1.affine_encrypted_text));
affine_cipher_text.close();
}

In essence I am setting values of the struct in the first .cpp file, but my 2nd .cpp file is printing out nothing for those char arrays that I have set in the first .cpp file. Should this not work using extern the way I have done it? If this is not the proper use of extern forgive me. If not any good ways to share a variable and its value across seperate .cpp files?

dan
  • 1
  • 2
    You declare your global variable with `extern` in the header file, and define it without `extern` in exactly one source file. – Igor Tandetnik Jan 26 '18 at 18:39
  • Can you explain why you declare it extern in the header and define it without in a source file? That answer on the question seems to say otherwise. – dan Jan 26 '18 at 18:52
  • No, the answer says exactly that. I'm not sure how you manage to read it otherwise - it's thoroughly detailed and perfectly clear. – Igor Tandetnik Jan 26 '18 at 18:58
  • I'm referring on the guidelines where he says you can do differently from what your saying. What exactly is wrong with the way I have it? To me as long as you define it without extern in one location it should work? – dan Jan 26 '18 at 19:07
  • Which guideline, specifically, do you believe contradicts my suggestion? – Igor Tandetnik Jan 26 '18 at 19:16
  • Wait. You have two separate, completely unrelated programs, each with its own `main`. You are not linking those two source files together into a single binary. I don't see by what magic you expect two unrelated programs to somehow see each other's data. That ain't how global variables work. – Igor Tandetnik Jan 26 '18 at 19:17
  • The guidelines where he says rules to be broken by experts only. Would the above way work if I bar the int main issue? – dan Jan 26 '18 at 19:38
  • If you attempt to link those two source files together, I predict you will see a linker error about duplicate definitions. – Igor Tandetnik Jan 26 '18 at 19:41
  • So in summary you declare your struct extern in the .h. Assign it in one of the source files. Then the other one no definition or declaration is needed because he will go look at the .h file see it is extern signifying it has been an assigned a clue elsewhere ... in this case the first source ? – dan Jan 26 '18 at 19:46

0 Answers0