Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Turning array in main into a global, to later be altered by main?

I have two arrays of the alphabet in the following format:

const char plain[26] = {'a','b',....'y','z'} // this is the the full alphabet
const char crypt[26] = {'i','d',....'m','x'}; // this is the the alphabet scrambled

The order of the alphabet in both arrays can change depending on input. This change happens in the main function.

The purpose of this is to match the letters of the string to the second, like an encryption. I compare characters to array values. So it would kind of look like this (simplified)

text[3] = 'yes';
changed[3];
if(text[0] == plain[25]){    //would be done under a for loop so 25 would be a changing integer value
    changed[0] = [crypt[25];
}

My code works under perfectly under the main function. I wanted to mention my purpose like this because I was having previous problems simply due to the type of array and formatting. And since the array is moved outside, I will probably/am running into those problems again.


Now I want to make the arrays global. The actual encryption happens in a function that does not take the arrays as a variable. But I want the function to have access to them.

Here's what it looks likes right now

const char plain[26];
const char crypt[26];
int maint(void){
    const char plain[26] = {'a','b',....'y','z'} \\values get changed here 
    const char crypt[26] = {'i','d',....'m','x'} \\and here

While this provides no errors, I dont get an output, I believe the other functions are using a blank array instead of the changed one (if the change even worked).

I've tried different array types, I believe the issue is in initialization or giving the array values.

Edit: To clarify, the two arrays can be in any order. A text file will randomize the order can give it to me in the format:

b,r
m,o
l,s
...
...
...

Both cases the alphabet is randomized. Where the first column would correspond to the first array (plain), second would be to second array (crypt).

If there's a way to read by columns and store in the format

plain = 'bml...'; \\whole alphabet randomized
crypt = 'ros...'; \\whole alphabet randomized

That would also work.

like image 764
Yee Kee Avatar asked Feb 08 '19 07:02

Yee Kee


3 Answers

The plain and crypt you have in main aren't the same as the global ones. Since you declare them again, they're new ones that are only visible in main. Thus you're not changing the global ones.

Instead, only declare them once globally and do assignment in the main function:

char plain[26];

int main(void) {
    memcpy(plain, "abcdefghijklmnopqrstuvwxyz", 26); //values get changed here
    return 0; // indicate successful program execution
}

Also note that there are some syntax errors in

const char plain[26] = {'a','b',....'y','z'} \\values get changed here 

Comments start with //, not \\, and you need a ; after a statement. Also, the int main should return an int in C.

Of course, if you don't need to actually change the memory and only assign it to predefined sets of characters, you can do it like this:

const char *plain;

int main(void) {
    plain = "abcdefghijklmnopqrstuvwxyz";
    return 0;
}

This way you can still read from it with syntax like plain[5], but you can't assign to it with, say plain[5] = 'a';.

like image 55
Blaze Avatar answered Nov 02 '22 23:11

Blaze


Remove "const char" before plain and crypt arrays in main function to see the actual issue.

“Const Char” before plan and crypt arrays actually declare two new local char array constants with same name. As “const” char array can only be initialized at the declaration time therefore initialization in main does not throw error because they are not same global conts arrays.

Instead of using const use Const pointer as suggested in below answer

like image 27
Anwar Avatar answered Nov 03 '22 01:11

Anwar


Another way to look at it is that plain and crypt will both decay to pointers on access (subject to the exceptions in) C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3). So why not just use global pointers to begin with that can then be reassigned as needed throughout your code?

This provides the flexibility of assignment from (1) string literals; (2) constant arrays; or (3) from compound literal initializers. You can #define a constant for the size (number of characters) plain and crypt point to.

For example:

#include <stdio.h>

#define NC 3    /* number of chars (26 for you) */

const char *plain, *crypt;  /* global pointers */

void prnchars (const char *arr)
{
    for (int i = 0; i < NC; i++)
        putchar (arr[i]);
    putchar ('\n');
}

int main (void) {

    plain = "abc";              /* assigning literals */
    crypt = "def";

    prnchars (plain);
    prnchars (crypt);

    crypt = "ghi";              /* reassign at will */

    prnchars (crypt);

    const char foo[] = "jkl";   /* constant arrays */
    crypt = foo;

    prnchars (crypt);

    crypt = (const char[]){'m', 'n', 'o'};  /* compound literals */

    prnchars (crypt);

    return 0;
}

Example Use/Output

$ ./bin/global_ptr
abc
def
ghi
jkl
mno

It's just another way of looking at the problem.

like image 41
David C. Rankin Avatar answered Nov 03 '22 00:11

David C. Rankin