0

好的,伙计们,这是我在这里的第一篇文章。我的 compsci 课程中最近的作业让我们编写了几个函数来基于简单的偏移量对字符串进行编码和解码。到目前为止,在我的加密函数中,我正在尝试将字符串中的大写字母转换为它们的 ASCII 等价物(一个 int),添加偏移量(并在 ASCII 值超过“Z”时进行调整),将该 int 转换回一个字符(新的加密字符)并将其放入新字符串中。我在这里编译得很好,但是当我运行它并输入简单的大写字符串时,它会给出一个分段错误(核心转储)错误。我在哪里错了?(注意:在尝试解决在 main 中产生一些奇怪错误的情况时,有一些注释掉的位)

#include <stdio.h>
#include <string.h>
#include <ctype.h>
//#include <stdlib.h>

char *encrypt(char *str, int offset){
   int counter; 
   char medianstr[strlen(str)];
   char *returnstr;// = malloc(sizeof(char) * strlen(str));
   for(counter = 0; counter < strlen(str); counter++){
      if(isalpha(str[counter]) && isupper(str[counter])){//If the character at current index is an alpha and uppercase
         int charASCII = (int)str[counter];//Get ASCII value of character
         int newASCII;       
         if(charASCII+offset <= 90 ){//If the offset won't put it outside of the uppercase range
            newASCII = charASCII + offset;//Just add the offset for the new value
            medianstr[counter] = (char)newASCII;
         }else{
            newASCII = 64 + ((charASCII + offset) - 90);//If the offset will put it outside the uppercase range, add the remaining starting at 64(right before A)
            medianstr[counter] = (char)newASCII;
         }
      } 
   }
   strcpy(returnstr, medianstr);
   return returnstr;
}
/*
char *decrypt(char *str, int offset){

}
*/

int main(){
   char *inputstr;
   printf("Please enter the string to be encrypted:");
   scanf("%s", inputstr);
   char *encryptedstr;
   encryptedstr = encrypt(inputstr, 5);
   printf("%s", encryptedstr);
   //free(encryptedstr);
   return 0;
}
4

3 回答 3

2

您使用一堆指针,但从不为它们分配任何内存。这将导致段错误。

实际上奇怪的是,你似乎知道你需要这样做,因为你已经有了代码,但是你把它注释掉了:

char *returnstr;// = malloc(sizeof(char) * strlen(str));

当您使用指针时,您需要将其“指向”分配的内存,它可以指向您通过请求的动态内存malloc()或静态内存(例如您声明的数组);当您完成动态内存时,您需要free()它,但是当您注释掉对 free 的调用时,您似乎再次知道这一点。

只需一个malloc()toinputstr和一个 forreturnstr就足以让这个工作。

于 2013-03-30T04:49:11.100 回答
1

不用多说,分段错误来自您对 scanf() 的使用。

scanf() 发生分段错误,因为它试图写入 *inputstr(输入str 指向的位置块);此时尚未分配。要调用 scanf(),您需要输入一个指针,它指向的内存地址首先被分配。

自然,要修复您想要的分段错误,请将内存分配给您的 char *inputstr。

动态分配 128 字节的内存(即指针将指向堆):

char *inputstr = (char *) malloc(128);

或者静态分配 128 字节的内存(即指针将指向堆栈):

char inputstr[128];
于 2013-03-30T04:56:10.403 回答
1

该功能有很多复杂性encrypt(),实际上并不是必需的。请注意,在循环的每次迭代中计算字符串的长度通常是一个代价高昂的过程。我在评论中指出:

What's with the 90 and 64? Why not use 'A' and 'Z'? And you've commented out the memory allocation for returnstr, so you're copying via an uninitialized pointer and then returning that? Not a recipe for happiness!

The other answers have also pointed out (accurately) that you've not initialized your pointer in main(), so you don't get a chance to dump core in encrypt() because you've already dumped core in main().

#include <ctype.h>
#include <stdlib.h>
#include <string.h>

char *encrypt(char *str, int offset)
{
    int len = strlen(str) + 1;
    char *returnstr = malloc(len);
    if (returnstr == 0)
        return 0;
    for (int i = 0; i < len; i++)
    {
        char c = str[i];
        if (isupper((unsigned char)c))
        {
            c += offset;
            if (c > 'Z')
                c = 'A' + (c - 'Z') - 1;
        }
        returnstr[i] = c;
    }
    return returnstr;
}

Long variable names are not always helpful; they make the code harder to read. Note that any character for which isupper() is true also satisfies isalpha(). The cast on the argument to isupper() prevents problems when the char type is signed and you have data where the unsigned char value is in the range 0x80..0xFF (the high bit is set). With the cast, the code will work correctly; without, you can get into trouble.

于 2013-03-30T05:03:12.280 回答