【问题标题】:c- Error when assigning structure member in functionc-在函数中分配结构成员时出错
【发布时间】:2017-07-11 16:20:57
【问题描述】:

我正在用 C 语言编写一个程序来查找停止者密码中的转换。

作为其中的一部分,我首先对要破译的消息执行所有可能的移位,0-26,我使用一个结构来存储移位和消息。为此,我将结构作为指针传递给函数。但是,当我尝试将结构的消息成员更改为解密消息时,我收到错误:'strcpy(s->message, cipherText); '。

在函数中,我还为结构成员分配了一个局部变量,这工作正常。

代码:

#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);
    }
}

【问题讨论】:

  • s-&gt;message : char message[]; 没有空格。
  • 问题是你有两个名为 s 的变量。内部的 int s 遮住了外部的 Solution *s。如果您使用 gcc,则 -Wshadow 标志非常适合定位此类问题。
  • @BjornA。谢谢,虽然这很简单,但我不敢相信我没有注意到冲突。也感谢编译器提示。

标签: c function pointers struct member


【解决方案1】:

问题是你没有正确关闭for(int s=...,编译器认为s-&gt;你指的是循环变量s而不是Solution* s函数参数。

这就是为什么您会收到 invalid type 错误。

以下是固定的(并且缩进更好)的版本:

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);
}

如果您让编译器警告-Wshadow 起作用,您将获得非常丰富的信息。

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) {

【讨论】:

    【解决方案2】:
    void Ceaser(struct Solution *s, char cipherText[], int mode){
    ....
    for (int s = 0; s <= 26; ++s){
    

    你能不能在这里看到明显的冲突 - 你使用了两次相同的变量名。 int s 将覆盖先前声明的 s for 循环范围,因此您的代码将无法与先前声明的代码进行交互。

    将第一个s 更改为适当的变量名称(即“解决方案”),这样您就可以避免冲突,并且变量的用途也很明显。单个字符变量不是很清楚它们的用途,即使它们只是用于 for 循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-03
      • 2016-05-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-14
      • 1970-01-01
      • 2020-05-26
      • 1970-01-01
      相关资源
      最近更新 更多