19----C/C++之加密&解密&带空格字符串的读入

  • 本文主要通过一道题目来讲解C语言相关的简单加密和解密,以及如何读入带有空格的字符串

小试牛刀

  • 题目描述

    在情报传递过程中,为了防止情报被截获,往往需要对情报用一定的方式加密。我们给出一种最简单的加密方法,对给定的一个字符串,把其中从 a∼y,A∼Y 的字母用其后继字母替代,把 z 和 Z用 a 和 A 替代,其他非字母字符不变。请根据该加密规则将输入的密码进行解密。

提示:这里需要进行解密操作,而不是加密。

  • 输入格式

      一行,加密后的字符串,长度不多于 10000 个字符。
    
  • 输出格式

      一行,将密码解密后的字符串。
    
  • 输入输出样例

输入

 Ifmmp !  Ipx  bsf  zpv! 

输出

 Hello !  How  are  you! 

根据题目的描述,我们的任务就是解密,即每个字母都由其前驱代替,a由z代替,A由Z代替,其余字符不变。


下面我们尝试写出代码:

  1. 方法一: 利用while()循环,结合getchar()逐个读入并解密赋值,当读到'\n'时自动结束读入,再输出即可。
#include

using namespace std;

char s[10001];
char c;
int i;
int main(void)
{
	while ((c = getchar()) != -1)//这里可以写!=-1 或者!=EOF  ,不能写!='\n';
	{
		if (c == 'a')s[i] = 'z';
		else if (c == 'A')s[i] = 'Z';
		else if ((c > 'A' && c <= 'Z') || (c > 'a' && c <= 'z')) s[i] = (char)((int)c - 1);
		else s[i] = c;
		i++;
	}
	for (int j = 0; j < i; j++)
	{
		cout << s[j];
	}
	return 0;
}
  • 这个方法的好处在于可以设置特定的终止字符,甚至终止位置,时间复杂度为O(n)。

  1. 方法二:利用fgets()函数直接读入一连串字符(遇到换行符时才停止)。再利用循环进行解密操作,完了输出即可。
#include
#include
using namespace std;

char s[10005];
char c;
int i;
int main(void)
{
	fgets(s, 10001, stdin);
	for (int i = 0; i < strlen(s); i++)
	{
		c = s[i];
		if (c == 'a')s[i] = 'z';
		else if (c == 'A')s[i] = 'Z';
		else if ((c > 65 && c <= 90) || (c > 97 && c <= 122) )s[i] = (char)((int)c - 1);
		else;

	}
	fputs(s, stdout);
	return 0;
}
  • 这个方法的好处在于可以一次性读入和输出带有空格的长字符串,省去了利用循环带来的时间消耗,时间复杂度为O(n)。

  1. 方法三:利用getline()函数进行指定位数输入,大多数情况下用于一整行(段)输入;strlen()函数用于获取字符串长度,然后边判断边输出。
#include//万能头文件
using namespace std;
char s[10001]; //定义字符串。
int n; //字符串长度。
int main(void)
{
	cin.getline(s,10000);
    //输入字符串,因为有空格,所以不能用cin<
    //最多10000位,末位自动为'\0',所以输入10000位,输入不够10000位就自动停止。
	n=strlen(s); //非空字符串长度。
	for(int i=0;i<n;i++) //输入时是从第0位到第n-1位。
	{
		if((s[i]>'a'&&s[i]<='z')||(s[i]>'A'&&s[i]<='Z'))
			s[i]--;
        //把b-z和B-Z替换成前一个字母。
		else if(s[i]=='a')
			s[i]='z';
        //把a替换成z。
		else if(s[i]=='A')
			s[i]='Z';
        //把A替换成Z。
        else;
        //其余字符不变
		cout<<s[i]; //边改边输出,减少时间消耗
	}
	return 0;
}
  • 这个方法和方法二有些类似,时间复杂度也为O(n)。

  1. 方法四:先利用getline(cin,s)输入带空格的字符串,(对于字符串来说,普通的 cin 只能读取没有空格的字符串;)再循环解密输出即可。
#include 
#include 
#include 
using namespace std;
string s;//这里用STL的字符串
int main(void) {
	getline(cin, s);//输入字符串
		for (int i = 0; i < s.length(); i++) {
			
			if ((s[i] > 'a' && s[i] <= 'z') || (s[i] > 'A' && s[i] <= 'Z'))
				s[i]--;
			//把b-z和B-Z替换成前一个字母。
			else if (s[i] == 'a')
				s[i] = 'z';
			//把a替换成z。
			else if (s[i] == 'A')
				s[i] = 'Z';
			//把A替换成Z。
			else;
		}
	cout << s;//直接输出
	return 0;
}

  • 此方法和方法二,方法三类似,只是输入字符串方式不一样罢了,时间复杂度也为O(n)。

要点剖析:

  • 下面我们来看看怎么读入带有空格的字符串,分别从C语言和C++的角度来讲解。

一、C语言中读入带有空格字符串的方法:

  1. 使用scanf函数:scanf函数默认以空格作为分隔符,可以使用%s格式化指示符来读取字符串,但它会在遇到空格时停止读取。为了读取带有空格的字符串,可以使用%[^\n]格式化指示符,它会读取除换行符外的所有字符。
#include 

int main() {
    char str[100];
    printf("Enter a string: ");
    scanf("%[^\n]", str);
    printf("You entered: %s\n", str);
    return 0;
}

  1. 使用fgets函数:fgets函数可以读取一行字符串,包括空格。它接受三个参数:要读取的字符串的地址、最大字符数和文件指针(可以是stdin)。注意,fgets函数会将换行符也读入字符串中。
#include 

int main() {
    char str[100];
    printf("Enter a string: ");
    fgets(str, sizeof(str), stdin);
    printf("You entered: %s\n", str);
    return 0;
}

由于gets()函数的不安全性,我们这里使用fgets()


  1. 使用getchar函数:getchar函数可以逐个字符读取输入。可以使用一个循环来读取字符,直到遇到换行符或达到最大字符数。
#include 

int main() {
    char str[100];
    printf("Enter a string: ");
    int i = 0;
    char c;
    while ((c = getchar()) != '\n' && i < sizeof(str) - 1) {
        str[i++] = c;
    }
    str[i] = '\0';
    printf("You entered: %s\n", str);
    return 0;
}

  • 这些方法可以读取带有空格的字符串,但需要注意输入的长度限制和处理换行符的方式。选择合适的方法取决于具体的需求和输入格式。

二、C++中读入带有空格字符串的方法:

  1. 使用cingetline()cin是C++的输入流对象,可以使用>>操作符来读取字符串。默认情况下,cin会以空格作为分隔符,因此会在遇到空格时停止读取。为了读取带有空格的字符串,可以使用getline函数。getline函数可以从输入流中读取一行字符串,包括空格。它接受两个参数:要读取的字符串对象和输入流对象(可以是cin)。注意,getline函数会将换行符也读入字符串中。
#include 
#include 

int main() {
    std::string str;
    std::cout << "Enter a string: ";
    std::getline(std::cin, str);
    std::cout << "You entered: " << str << std::endl;
    return 0;
}

  1. 在C++中,还有一种方法可以读取带有空格的字符串,即使用stringstreamstringstream是C++标准库中的一个类,可以将字符串视为流进行处理。通过将输入的字符串存储在stringstream对象中,可以使用>>操作符来读取带有空格的字符串。

以下是使用stringstream读取带有空格的字符串的示例代码:

#include 
#include 
#include 

int main() {
    std::string input;
    std::cout << "Enter a string: ";
    std::getline(std::cin, input);

    std::stringstream ss(input);
    std::string str;
    while (ss >> str) {
        std::cout << "Word: " << str << std::endl;
    }

    return 0;
}
  • 在上述代码中,首先使用getline函数读取一行输入字符串。然后,将该字符串存储在stringstream对象ss中。使用>>操作符从ss中逐个读取字符串,每次读取一个单词,并将其打印出来。

  • 这种方法适用于需要逐个处理输入字符串中的单词的场景。可以根据具体需求对读取到的字符串进行进一步处理。


  1. 还有一种方法,也是使用getline()函数。getline()函数可以动态分配内存,并一次性读取整行输入,并将其存储在指定的字符数组中。

以下是使用getline()函数读取带有空格的字符串的示例代码:

#include 
#include 

int main() {
    char *str = NULL;
    size_t bufsize = 0;
    printf("Enter a string: ");
    getline(&str, &bufsize, stdin);
    printf("You entered: %s", str);
    free(str);
    return 0;
}
  • 在上述代码中,首先定义一个字符指针str,并将其初始化为NULL。然后,使用getline()函数来读取整行输入,并将其存储在str指针指向的内存中。getline()函数会自动分配足够的内存来存储输入的字符串,并将字符串的长度存储在bufsize变量中。

  • 需要注意的是,使用getline()函数需要包含头文件,并且在使用完之后需要调用free()函数来释放动态分配的内存,以防止内存泄漏。


三、总结与思考:

  • 本次我们学习了如何输入带有空格的字符串,且分别从C语言和C++的角度进行了讲解,利用fgets(),getline(),getchar()等都是不错的方法。相信通过本篇文章的学习,你对这方面的题目将不再存有疑问。

19----C/C++之加密&解密&带空格字符串的读入_第1张图片

你可能感兴趣的:(C++,c++,c语言,算法,html,xhtml)