我正在尝试构建一个程序,该程序将对文本文件执行简单的凯撒密码,该文件具有单个字符串,并且每行都没有空格。由于某种原因,我的密码功能没有转移文本,并且我截断了各种长度的字符的字符串。您可以在while循环中看到我搞砸了我的函数调用吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
{
int i = 0;
int len = strlen(ch);
while (ch[i] < len)
{
if (islower(ch[i]))
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
else
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
}i++;
printf("Caesar Cipher = %s\n", ch);
}
int main(void)
{
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
{
printf("Can't open %s\n", FILE_NAME);
exit(EXIT_FAILURE);
}
while(fgets(c, sizeof(c), fp) != 0)
{
printf("%s\n", c);
caeser(c, 1);
}
fclose(fp);
fp = NULL;
return 0;
}
答案 0 :(得分:0)
我对您的代码做了一些更改,并用粗体标记了它们。
数组从0开始,结尾为n-1个字符。
您检查了ch [i] 在每次迭代中,您需要将i递增1。这样您就可以获得下一个字符。 为获得更好的设计,请尝试将可打印格式打磨至主要功能,而不是在功能中打印。您应该返回一个指向字符串的指针并将其打印在main中。#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
{
int i = 0;
int len = strlen(ch);
while (**i < len-1**)
{
if (islower(ch[i]))
{
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
**i++;**
}
else
{
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
**i++;**
}
}
printf("Caesar Cipher = %s\n", ch);
}
int main(void)
{
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
{
printf("Can't open %s\n", FILE_NAME);
exit(EXIT_FAILURE);
}
while(fgets(c, sizeof(c), fp) != 0)
{
printf("%s\n", c);
caeser(c, 1);
}
fclose(fp);
fp = NULL;
return 0;
}
答案 1 :(得分:0)
请注意,fgets
可能在字符串末尾返回“换行符”('\n'
)。您可能要从缓冲区中删除换行符。
如果字符串中包含空格,'\n'
字符或A-Z或a-z范围以外的任何字符,请忽略这些字符,因为它们不符合caeser密码的逻辑。
char * c = malloc( sizeof(char) * 1000); while(fgets(c, sizeof(c), fp) != 0) { ... }
如注释中所述,c
是一个指针,在这种情况下,sizeof(c)
通常是4或8。因此,您告诉fgets
最多读取4或8个字节。但是文件中的每一行都可能更长。如果您已声明,请说char c[1000];
,然后sizeof(c)
将是1000
。否则,请不要在此处使用sizeof
运算符。
while(i < len) {...}i++;
您想要到达字符串的末尾,并在循环内递增,因此将条件更改为:
while(i < len) {... i++;}
最后,c
或ch
通常用于表示字符。这是非正式的,并不重要,但是如果您声明字符串,则使用buf
或str
更为清楚。
示例:
void caeser(char *buf, int shift)
{
int i = 0;
int len = strlen(buf);
while(i < len)
{
char c = buf[i];
if(c >= 'a' && c <= 'z')
buf[i] = (c - 'a' + shift) % 26 + 'a';
else if(c >= 'A' && c <= 'Z')
buf[i] = (c - 'A' + shift) % 26 + 'A';
//else, do nothing if chararacter is not between a-z or A-Z
i++;
}
}
int main(void)
{
FILE* fp = fopen(FILE_NAME, "r");
if(fp == NULL)
{
printf("Can't open %s\n", FILE_NAME);
exit(EXIT_FAILURE);
}
int buf_size = 1000;
char *buf = malloc(sizeof(char) * buf_size);
while(fgets(buf, buf_size, fp))
{
//optional: remove the new line character if any
int len = strlen(buf);
if(len && buf[len - 1] == '\n')
buf[len - 1] = 0;
printf("plain : %s\n", buf);
caeser(buf, 1);
printf("cipher: %s\n\n", buf);
}
//free the buffer allocated with malloc
free(buf);
fclose(fp);
return 0;
}