我如何将这些字符沿着字母表3空格转移而不会进入不与字母分开的其他字符?

时间:2015-02-08 21:18:01

标签: c encryption non-ascii-characters

所以,我必须将我收到的每个字符都转移到字母表中3个空格中,当它击中字母表的结尾时,它会返回。所以A将是X,B将是Y ......所以就这样。我唯一的问题是当它超过z时,它会打印^ _' 知道为什么会这样吗?我知道它与我的encrypt_file函数中的循环变量有关。是的我知道这个功能不完整,因为它不会寻找大写字母,我只是想让我的测试用例失效,所以我几乎可以复制并粘贴剩下的部分。

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

#define OP_ENCRYPT "-e"
#define OP_DECRYPT "-d"

enum method
{
	ENCRYPT,
	DECRYPT
};

typedef int (*converter_t)(int);

int encrypt_file(int c)
{
	if(c >= 'a' && c <= 'z')	
	{
		if((c - 3) >= 'z')
		{
			return c + 3;
		}
		else
		{
			return c - 3;
		}
	
	}
	else
	{
		return c;
	} 
}


int decrypt_file(int c)
{
	int j;	
	if(c<= 'A' && c>= 'Z')
	{
		if((j = c - 3) >= 'Z')
		{	
			c = j;	
			return c;	
		}	
		else
		{
			j = c + 3;
			c = j;	
			return c;
		}
	}
	else if(c<= 'a' && c>= 'z')
	{
		if((j = c - 3) >= 'z')
		{	
			c = j;	
			return c;
		}	
		else
		{
			j = c + 3;
			c = j;	
			return c;
		}
	}
	return c;	
}


enum method conversion_method(const char *arg)
{
	if (strcmp(arg,OP_ENCRYPT) == 0)
	{
		return ENCRYPT;
	}
	if (strcmp(arg,OP_DECRYPT) == 0)
	{
		return DECRYPT;
	}	
	else
	{
		return ENCRYPT;
	}
}

converter_t converter(enum method mode)
{
	switch (mode)
	{
		case ENCRYPT:
			return encrypt_file;
		case DECRYPT:
			return decrypt_file;
		default:
			return encrypt_file;
	}
}
int is_option(const char *str)
{
	return (strcmp(str, OP_ENCRYPT) == 0) || (strcmp(str,OP_DECRYPT) == 0); 
}

void convert( FILE *src, FILE *dest, converter_t method)
{
	unsigned int ch;

	while ((ch = fgetc(src)) != EOF)
	{
		fprintf(dest, "%c", (*method)(ch));
	}
}

int main(int argc, const char *argv[])
{
	FILE *src = stdin;
	FILE *dest = stdout;
	enum method method = ENCRYPT;
		
	if(argc ==2 ) 
	{
		if (is_option(argv[1])) 
		{
			method = conversion_method(argv[1]);
		}
		else
		{
			src = fopen(argv[1], "r");
			if (src == NULL)
			{
				fprintf(stderr, "%s: unable to open %s\n", argv[0], argv[1]);
				exit(EXIT_FAILURE);
			}
		}
	}
	else if (argc == 3) 
	{
		if (is_option(argv[1]))
		{
			method = conversion_method(argv[1]);
			src = fopen(argv[2], "r");
			if (src == NULL) 
			{
				fprintf(stderr, "%s: unable to open %s\n", argv[0], argv[2]);
				exit(EXIT_FAILURE);
			}
		}
		else
		{
			fprintf(stderr, "%s: invalid option %s\n", argv[0], argv[1]);
			exit(EXIT_FAILURE);
		}
	}

	convert(src, dest, converter(method));

	return EXIT_SUCCESS;
}	

1 个答案:

答案 0 :(得分:0)

你正在考虑 waaay 比你需要的更难,你迷路了。在这里,看看这个:

#include <stdio.h>
#include <assert.h>

int encrypt_char( int c )
{
    assert( c >= 'a' && c <= 'z' );
    c -= 3;
    if( c < 'a' )
        c += 26;
    return c;
}

int decrypt_char( int c )
{
    assert( c >= 'a' && c <= 'z' );
    c += 3;
    if( c > 'z' )
        c -= 26;
    return c;   
}

void encrypt_text( char* ptext )
{
    for( ; *ptext != 0; ptext++ )
        *ptext = encrypt_char( *ptext );
}

void decrypt_text( char* ptext )
{
    for( ; *ptext != 0; ptext++ )
        *ptext = decrypt_char( *ptext );
}

static char text[256] = "abcdefghijklmnopqrstuvwxyz";

int main( int argc, const char *argv[] )
{
    printf( "ORIGINAL:  %s\n", text );
    encrypt_text( text );
    printf( "ENCRYPTED: %s\n", text );
    decrypt_text( text );
    printf( "DECRYPTED: %s\n", text );
    return 0;
}