Search code examples
cfunctionpointersstructmember

c- Error when assigning structure member in function


I am writing a program in C to find the shift in a ceaser cipher.

As part of this I first perform every possible shift, 0-26, on the message to decipher, I use a struct to store the shift and the message. To do this I have passed a structure to a function as a pointer. However, when I try to change the message member of the struct to the deciphered message I get the error: invalid type argument of '->' (have 'int') on the line 'strcpy(s->message, cipherText);'.

In the function I also assign a local variable to a structure member and this works fine.

Code:

#include <stdio.h>
#include <string.h>
#define ENCRYPT 0
#define DECRYPT 1

struct Solution {
    int key;
    char message[];
};

void Ceaser(struct Solution *s, char cipherText[], int mode);

void main(){
    struct Solution solutions[26];
    char cipherText[] = "lipps, asvph.";

    for (int i = 0; i <= 26; ++i) {
        solutions[i].key = i;
        Ceaser(&solutions[i], cipherText, DECRYPT);
        printf("Key: %d\tPlain text: %s\n", solutions[i].key, 
        solutions[i].message);
    }
}

void Ceaser(struct Solution *s, char cipherText[], int mode) {

    int len = strlen(cipherText);
    int c;
    int key = s->key;

    for (int s = 0; s <= 26; ++s) {
        if (mode == DECRYPT) {
            key *= -1;
        }

        for (int i = 0; i < len; ++i) {
            c = cipherText[i];

            if (c >= 'A' && c <= 'Z') {
                cipherText[i] = 'A' + ((c + key - 'A') % 26);           
            } else if (c >= 'a' && c <= 'z') {
                cipherText[i] = 'a' + ((c + key - 'a') % 26);           
            }
        }
    //Error occurs below
    strcpy(s->message, cipherText);
    }
}

Solution

  • The problem is that you are not closing the for(int s=... correctly and the compiler thinks that by s-> you are referring to the loop variable s instead of the Solution* s function parameter.

    That is why you get that invalid type error.

    The following is a fixed (and better indented) version:

    void Ceaser(struct Solution *s, char cipherText[], int mode) {
      int len = strlen(cipherText);
      int c;
      int key = s->key;
    
      for (int s = 0; s <= 26; ++s) {
        if (mode == DECRYPT) {
          key *= -1;
        }
    
        for (int i = 0; i < len; ++i) {
          c = cipherText[i];
    
          if (c >= 'A' && c <= 'Z') {
            cipherText[i] = 'A' + ((c + key - 'A') % 26);
          } else if (c >= 'a' && c <= 'z') {
            cipherText[i] = 'a' + ((c + key - 'a') % 26);
          }
        }
      } //<--------was missing 
    
      strcpy(s->message, cipherText);
    }
    

    If you let the compiler warning -Wshadow works what you get is very informative.

    g++
    test.cpp:65:30: note: shadowed declaration is here
     void Ceaser(struct Solution *s, char cipherText[], int mode) {
    
    clang++
    note: previous declaration is here
    void Ceaser(struct Solution *s, char cipherText[], int mode) {
    
    
    icpc
    warning #1599: declaration hides parameter "s" (declared at line 65)
        for (int s = 0; s <= 26; ++s) {