如何使用 'do while' 循环重复 'for' 循环
How do I repeat a 'for' loop using a 'do while' loop
这是我的 Vigenere 密码。我正在尝试使用 do while 循环对用户输入的键重复迭代。密钥应用于用户输入的明文单词,一次输入一个字母。我需要能够遍历密钥直到明文单词结束,以防密钥比单词短。我尝试使用 do-while 循环添加重复,第一个 for 循环是关键迭代。
'do while' 循环的最后一行抛出未声明标识符 i 的错误。这是我遇到的唯一错误。内部 'for' 循环来自凯撒密码并通过了所有检查。我认为我的 do while 循环是错误的。如果我添加 char* word[i] 或 word[i] 的定义,无论我把它放在哪里,我都会得到一个遮蔽错误。我想使用这段代码而不是完全改变它,所以我知道是否可以这样做。但是,我们欢迎任何建议。
int main(int argc, char* argv[])
{
if (argc<2) //key
{
printf("Please enter your word key"); //prompts if no key is entered
return 1;
}
char* key = (argv[1]);
if(argc>=2)
{
printf("plaintext:");
char* word = GetString();
printf("ciphertext:");
do
{ //starts loop to repeat following for loop
for(int l=0; l<strlen(key); l++) //iterate over letters in key
{
int num=l;
for(int i=0; i<strlen(word); i++) //iterates through word entered by user as plaintext
{
if(isupper(word[i])) //if original characters are uppercase
{
int cipher = (word[i] + num -65) % 26 + 65;
printf("%c", cipher);
}
else if(islower(word[i])) //if original characters are lowercase
{
int cipher = (word[i] + num - 97) % 26 + 97;
printf("%c", (cipher));
}
else //all other types of characters
{
printf("%c", word[i]);
}
}
}
printf("\n");
}while((word[i])<strlen(word)); // loop to recommence iterating over letters in the key (i throwing undeclared identifier error)
}
}
我认为你的循环 [levels] 太多了。
如果密钥长度在单词完成之前用完,则从单词的开头重新开始加密单词(即错误)。
主要目的是遍历所有单词字符。递增 i
的 单个 循环有效, 提供 它也递增 l
[模密钥长度].
这是一个清理过的版本[请原谅无偿的样式清理]:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// NOTE: I don't have GetString on my system
char *FakeGetString(void);
int
main(int argc, char *argv[])
{
// key
// prompts if no key is entered
if (argc < 2) {
printf("Please enter your word key");
return 1;
}
char *key = (argv[1]);
int klen = strlen(key);
if (argc >= 2) {
printf("plaintext:");
#if 0
char *word = GetString();
#else
char *word = FakeGetString();
#endif
int wlen = strlen(word);
printf("ciphertext:");
// current key index
int l = 0;
// starts loop to repeat following for loop
// iterates through word entered by user as plaintext
// advance to next key char [with wrap to beginning if we're short]
for (int i = 0; i < wlen; ++i, l = (l + 1) % klen) {
int num = key[l];
int cipher;
// if original characters are uppercase
if (isupper(word[i])) {
cipher = (word[i] + num - 65) % 26 + 65;
}
// if original characters are lowercase
else if (islower(word[i])) {
cipher = (word[i] + num - 97) % 26 + 97;
}
// all other types of characters
else {
cipher = word[i];
}
printf("%c", cipher);
}
printf("\n");
}
return 0;
}
// NOTE: I don't have GetString on my system
char *
FakeGetString(void)
{
static char buf[1000];
char *cp;
fgets(buf,sizeof(buf),stdin);
cp = strchr(buf,'\n');
if (cp != NULL)
*cp = 0;
return buf;
}
更新:
我写的上面的代码非常接近,但不是 Vigenere,因为你原来的方程式不对。键值必须是 offset/row 数字,因此需要从中减去 'A'
(即关键字只能是大写)。
所以,这是更正后的版本[有一些额外的清理]:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// NOTE: I don't have GetString on my system
char *FakeGetString(void);
int
baseof(int chr)
{
int base;
// if original character is uppercase
if (isupper(chr)) {
base = 'A';
}
// if original character is lowercase
else if (islower(chr)) {
base = 'a';
}
// anything else
else
base = 0;
return base;
}
int
main(int argc, char *argv[])
{
int kval;
int base;
int i;
// key
// prompts if no key is entered
if (argc < 2) {
printf("Please enter your word key\n");
return 1;
}
char *key = argv[1];
int klen = strlen(key);
// key must be uppercase and we only want row numbers
for (i = 0; i < klen; ++i) {
kval = key[i];
base = baseof(kval);
if (base) {
key[i] = kval - base;
continue;
}
printf("Key value must be only A-Z\n");
return 1;
}
if (argc >= 2) {
printf("plaintext:");
#if 0
char *word = GetString();
#else
char *word = FakeGetString();
#endif
int wlen = strlen(word);
printf("ciphertext:");
// starts loop to repeat following for loop
// iterates through word entered by user as plaintext
// advance to next key char [with wrap to beginning if we're short]
for (i = 0; i < wlen; ++i) {
int wval = word[i];
int cipher;
base = baseof(wval);
// uppercase or lowercase
if (base) {
kval = key[i % klen];
cipher = ((wval - base) + kval) % 26 + base;
}
// all other types of characters
else {
cipher = wval;
}
printf("%c",cipher);
}
printf("\n");
}
return 0;
}
// NOTE: I don't have GetString on my system
char *
FakeGetString(void)
{
static char buf[1000];
char *cp;
fgets(buf,sizeof(buf),stdin);
cp = strchr(buf,'\n');
if (cp != NULL)
*cp = 0;
return buf;
}
更新#2:
Your code passed all check50 checks except this one: :( encrypts "world, say hello!" as "xoqmd, rby gflkp!" using "baz" as keyword \ expected output, but not "ciphertext:xoqmd, szz gflkp!\n". It didn't encipher just the word 'say' properly, which is weird.
我使用 Vigenere 维基百科页面上的测试 data/example 对其进行了测试,但它只有一个现成的测试示例 [没有 空格或标点符号]。
This was the only check which contained a space (before the word 'say'). The spaces have to be directly copied. Perhaps that's why.
空格是直接复制过来的,这样就可以了。但是...
正确的方法是,当复制非字母字符时,键索引必须而不是递增。
我的版本使用 i
索引短语,使用 i % klen
索引键,因此键索引 总是 [有效] 递增。这就是错误。
讽刺的是,我也曾想过这个问题,但当时没有扩展的测试数据
因此,解决方案是将索引变量分开[再次:-)]。
这是更正后的版本。当我修复它时,我将 i
变量重命名为更具描述性的内容(例如 widx
)并(重新)创建了键的索引变量(例如 kidx
)。
请注意,现在 kidx
仅 在实际加密字符时递增。 "pass through" 案例 不是
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// NOTE: I don't have GetString on my system
char *FakeGetString(void);
int
baseof(int chr)
{
int base;
// if original character is uppercase
if (isupper(chr)) {
base = 'A';
}
// if original character is lowercase
else if (islower(chr)) {
base = 'a';
}
// anything else
else
base = 0;
return base;
}
int
main(int argc, char *argv[])
{
int kval;
int base;
int widx;
int kidx;
// key
// prompts if no key is entered
if (argc < 2) {
printf("Please enter your word key\n");
return 1;
}
char *key = argv[1];
int klen = strlen(key);
// key must be uppercase and we only want row numbers
for (kidx = 0; kidx < klen; ++kidx) {
kval = key[kidx];
base = baseof(kval);
if (base) {
key[kidx] = kval - base;
continue;
}
printf("Key value must be only A-Z\n");
return 1;
}
if (argc < 2)
return 1;
printf("plaintext:");
#if 0
char *word = GetString();
#else
char *word = FakeGetString();
#endif
int wlen = strlen(word);
printf("ciphertext:");
kidx = 0;
// starts loop to repeat following for loop
// iterates through word entered by user as plaintext
// advance to next key char [with wrap to beginning if we're short]
for (widx = 0; widx < wlen; ++widx) {
int wval = word[widx];
int cipher;
base = baseof(wval);
// uppercase or lowercase
if (base) {
kval = key[kidx];
cipher = ((wval - base) + kval) % 26 + base;
kidx = (kidx + 1) % klen;
}
// all other types of characters
else {
cipher = wval;
}
printf("%c",cipher);
}
printf("\n");
return 0;
}
// NOTE: I don't have GetString on my system
char *
FakeGetString(void)
{
static char buf[1000];
char *cp;
fgets(buf,sizeof(buf),stdin);
cp = strchr(buf,'\n');
if (cp != NULL)
*cp = 0;
return buf;
}
这是我的 Vigenere 密码。我正在尝试使用 do while 循环对用户输入的键重复迭代。密钥应用于用户输入的明文单词,一次输入一个字母。我需要能够遍历密钥直到明文单词结束,以防密钥比单词短。我尝试使用 do-while 循环添加重复,第一个 for 循环是关键迭代。
'do while' 循环的最后一行抛出未声明标识符 i 的错误。这是我遇到的唯一错误。内部 'for' 循环来自凯撒密码并通过了所有检查。我认为我的 do while 循环是错误的。如果我添加 char* word[i] 或 word[i] 的定义,无论我把它放在哪里,我都会得到一个遮蔽错误。我想使用这段代码而不是完全改变它,所以我知道是否可以这样做。但是,我们欢迎任何建议。
int main(int argc, char* argv[])
{
if (argc<2) //key
{
printf("Please enter your word key"); //prompts if no key is entered
return 1;
}
char* key = (argv[1]);
if(argc>=2)
{
printf("plaintext:");
char* word = GetString();
printf("ciphertext:");
do
{ //starts loop to repeat following for loop
for(int l=0; l<strlen(key); l++) //iterate over letters in key
{
int num=l;
for(int i=0; i<strlen(word); i++) //iterates through word entered by user as plaintext
{
if(isupper(word[i])) //if original characters are uppercase
{
int cipher = (word[i] + num -65) % 26 + 65;
printf("%c", cipher);
}
else if(islower(word[i])) //if original characters are lowercase
{
int cipher = (word[i] + num - 97) % 26 + 97;
printf("%c", (cipher));
}
else //all other types of characters
{
printf("%c", word[i]);
}
}
}
printf("\n");
}while((word[i])<strlen(word)); // loop to recommence iterating over letters in the key (i throwing undeclared identifier error)
}
}
我认为你的循环 [levels] 太多了。
如果密钥长度在单词完成之前用完,则从单词的开头重新开始加密单词(即错误)。
主要目的是遍历所有单词字符。递增 i
的 单个 循环有效, 提供 它也递增 l
[模密钥长度].
这是一个清理过的版本[请原谅无偿的样式清理]:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// NOTE: I don't have GetString on my system
char *FakeGetString(void);
int
main(int argc, char *argv[])
{
// key
// prompts if no key is entered
if (argc < 2) {
printf("Please enter your word key");
return 1;
}
char *key = (argv[1]);
int klen = strlen(key);
if (argc >= 2) {
printf("plaintext:");
#if 0
char *word = GetString();
#else
char *word = FakeGetString();
#endif
int wlen = strlen(word);
printf("ciphertext:");
// current key index
int l = 0;
// starts loop to repeat following for loop
// iterates through word entered by user as plaintext
// advance to next key char [with wrap to beginning if we're short]
for (int i = 0; i < wlen; ++i, l = (l + 1) % klen) {
int num = key[l];
int cipher;
// if original characters are uppercase
if (isupper(word[i])) {
cipher = (word[i] + num - 65) % 26 + 65;
}
// if original characters are lowercase
else if (islower(word[i])) {
cipher = (word[i] + num - 97) % 26 + 97;
}
// all other types of characters
else {
cipher = word[i];
}
printf("%c", cipher);
}
printf("\n");
}
return 0;
}
// NOTE: I don't have GetString on my system
char *
FakeGetString(void)
{
static char buf[1000];
char *cp;
fgets(buf,sizeof(buf),stdin);
cp = strchr(buf,'\n');
if (cp != NULL)
*cp = 0;
return buf;
}
更新:
我写的上面的代码非常接近,但不是 Vigenere,因为你原来的方程式不对。键值必须是 offset/row 数字,因此需要从中减去 'A'
(即关键字只能是大写)。
所以,这是更正后的版本[有一些额外的清理]:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// NOTE: I don't have GetString on my system
char *FakeGetString(void);
int
baseof(int chr)
{
int base;
// if original character is uppercase
if (isupper(chr)) {
base = 'A';
}
// if original character is lowercase
else if (islower(chr)) {
base = 'a';
}
// anything else
else
base = 0;
return base;
}
int
main(int argc, char *argv[])
{
int kval;
int base;
int i;
// key
// prompts if no key is entered
if (argc < 2) {
printf("Please enter your word key\n");
return 1;
}
char *key = argv[1];
int klen = strlen(key);
// key must be uppercase and we only want row numbers
for (i = 0; i < klen; ++i) {
kval = key[i];
base = baseof(kval);
if (base) {
key[i] = kval - base;
continue;
}
printf("Key value must be only A-Z\n");
return 1;
}
if (argc >= 2) {
printf("plaintext:");
#if 0
char *word = GetString();
#else
char *word = FakeGetString();
#endif
int wlen = strlen(word);
printf("ciphertext:");
// starts loop to repeat following for loop
// iterates through word entered by user as plaintext
// advance to next key char [with wrap to beginning if we're short]
for (i = 0; i < wlen; ++i) {
int wval = word[i];
int cipher;
base = baseof(wval);
// uppercase or lowercase
if (base) {
kval = key[i % klen];
cipher = ((wval - base) + kval) % 26 + base;
}
// all other types of characters
else {
cipher = wval;
}
printf("%c",cipher);
}
printf("\n");
}
return 0;
}
// NOTE: I don't have GetString on my system
char *
FakeGetString(void)
{
static char buf[1000];
char *cp;
fgets(buf,sizeof(buf),stdin);
cp = strchr(buf,'\n');
if (cp != NULL)
*cp = 0;
return buf;
}
更新#2:
Your code passed all check50 checks except this one: :( encrypts "world, say hello!" as "xoqmd, rby gflkp!" using "baz" as keyword \ expected output, but not "ciphertext:xoqmd, szz gflkp!\n". It didn't encipher just the word 'say' properly, which is weird.
我使用 Vigenere 维基百科页面上的测试 data/example 对其进行了测试,但它只有一个现成的测试示例 [没有 空格或标点符号]。
This was the only check which contained a space (before the word 'say'). The spaces have to be directly copied. Perhaps that's why.
空格是直接复制过来的,这样就可以了。但是...
正确的方法是,当复制非字母字符时,键索引必须而不是递增。
我的版本使用 i
索引短语,使用 i % klen
索引键,因此键索引 总是 [有效] 递增。这就是错误。
讽刺的是,我也曾想过这个问题,但当时没有扩展的测试数据
因此,解决方案是将索引变量分开[再次:-)]。
这是更正后的版本。当我修复它时,我将 i
变量重命名为更具描述性的内容(例如 widx
)并(重新)创建了键的索引变量(例如 kidx
)。
请注意,现在 kidx
仅 在实际加密字符时递增。 "pass through" 案例 不是
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// NOTE: I don't have GetString on my system
char *FakeGetString(void);
int
baseof(int chr)
{
int base;
// if original character is uppercase
if (isupper(chr)) {
base = 'A';
}
// if original character is lowercase
else if (islower(chr)) {
base = 'a';
}
// anything else
else
base = 0;
return base;
}
int
main(int argc, char *argv[])
{
int kval;
int base;
int widx;
int kidx;
// key
// prompts if no key is entered
if (argc < 2) {
printf("Please enter your word key\n");
return 1;
}
char *key = argv[1];
int klen = strlen(key);
// key must be uppercase and we only want row numbers
for (kidx = 0; kidx < klen; ++kidx) {
kval = key[kidx];
base = baseof(kval);
if (base) {
key[kidx] = kval - base;
continue;
}
printf("Key value must be only A-Z\n");
return 1;
}
if (argc < 2)
return 1;
printf("plaintext:");
#if 0
char *word = GetString();
#else
char *word = FakeGetString();
#endif
int wlen = strlen(word);
printf("ciphertext:");
kidx = 0;
// starts loop to repeat following for loop
// iterates through word entered by user as plaintext
// advance to next key char [with wrap to beginning if we're short]
for (widx = 0; widx < wlen; ++widx) {
int wval = word[widx];
int cipher;
base = baseof(wval);
// uppercase or lowercase
if (base) {
kval = key[kidx];
cipher = ((wval - base) + kval) % 26 + base;
kidx = (kidx + 1) % klen;
}
// all other types of characters
else {
cipher = wval;
}
printf("%c",cipher);
}
printf("\n");
return 0;
}
// NOTE: I don't have GetString on my system
char *
FakeGetString(void)
{
static char buf[1000];
char *cp;
fgets(buf,sizeof(buf),stdin);
cp = strchr(buf,'\n');
if (cp != NULL)
*cp = 0;
return buf;
}