用空格迭代字符串
Iterating over string with whitespace
我目前正在编写一个小轮换程序。但是我在处理 "this is a test" 这样的字符串时遇到了麻烦。当我有这样一个字符串时,它只对前 4 个字符而不是整个字符串进行编码。似乎空格正在破坏某些东西。我试图用 if 语句忽略空格,但这不起作用,我也不知道为什么。你知道这个问题吗?
是的...代码是非常实验性的所以请不要对 const 数组大小和类似的东西生气..
#include <stdio.h>
#include <stdlib.h>
#define alphabetsize 26
char alphabet[alphabetsize] = {'a','b','c','d','e','f','g','h','i','j',
'k','l','m','n','o','p','q','r','s','t',
'u','v','w','x','y','z'};
char lookup[alphabetsize] = {'0'};
char target[100] = {' '};
int search(char ch){
int i = 0;
for( ; i < alphabetsize; i++){
if(alphabet[i] == ch) return i;
}
}
char* rotate(char string[], int rotn){
int i = 0;
for( ; i < alphabetsize ; i++){
lookup[rotn] = alphabet[i];
rotn++;
if(rotn == (alphabetsize)) rotn = 0;
}
i = 0;
int index = 0;
for( ; i < 100; i++){
printf("%d\n", i );
if(string[i] != ' '){
index = search(string[i]);
target[i] = lookup[index];
}
}
printf("%s\n", target);
return target;
}
int main(int argc, char *argv[]){
int rotn = strtol(argv[2], NULL, 10);
printf("String: %s\n", argv[1]);
printf("Used Rotation degree: %d\n", rotn);
char* string = rotate(argv[1], rotn);
printf("Decrypted/Encrypted String: %s\n", string);
return 0;
}
这不能解决您的代码问题,并且是一个代码示例,由于其混淆可能不会让您获得好成绩,但您必须意识到 'rotN' 类型的问题如果您了解 ASCII 字符集的布局,则可以通过模块化数学轻松解决...
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char* rotate(char *s, int rotn)
{
char *s1=s;
for(;*s!='[=10=]'; s++) if(isalpha(*s))
*s = ((*s>'Z')?'a':'A')+(((*s-((*s>'Z')?'a':'A'))+rotn)%26);
return s1;
}
int main(int argc, char *argv[])
{
int rotn = strtol(argv[2], NULL, 10);
printf("String: %s\n", argv[1]);
printf("Used Rotation degree: %d\n", rotn);
char* string = rotate(argv[1], rotn);
printf("Decrypted/Encrypted String: %s\n", string);
return 0;
}
您的部分问题出在 search
,如果在 alphabet
中找不到 ch
,则无法 return 值。实际上,这意味着它将 return 一个未知值,然后您可以在不进行任何检查的情况下使用它来索引 lookup
数组。
根据内存的随机内容,您可以在 target
数组中插入空格或 NUL
个字符。
这实际上是由您的 rotate
函数触发的,该函数不会检查输入字符串中是否存在 NUL
并且不会在字符串末尾终止。
测试
if(string[i] != ' ')
允许在输入字符串中使用不可避免的 NUL
来调用 search
。然后您继续使用随机值调用搜索另外八十次左右 - 其中大部分不太可能在 'a'...'z'
中
一旦您使用非小写字符调用 search
,您的程序就会进入未定义行为的世界。
最后,正如@gaemaf 所提到的,循环中的输出索引需要独立于输入索引i
。当您跳过输入中的空格时,您也会提前输出指针(因为您对两者都使用 i
)。
初始化target[100] = {' '}
只初始化数组的第一个位置。其余部分包含二进制零,printf
in main
插入为字符串的结尾。因此,即使您旋转整个字符串,也只会打印出第一个单词。
要进行测试,请尝试输入字符串 "a bc def"。我怀疑你只会打印出一个字符。
我发现了你的问题,请尝试告诉我:
在旋转函数中更改您的 for:
int targetIndex = 0;
for (; i < 100; i++){
printf("%d\n", i);
if (string[i] != ' '){
index = search(string[i]);
target[targetIndex++] = lookup[index];
}
}
否则,因为您的目标被初始化为 NULL,您将永远看不到完整的结果。
要解决您的问题,您需要添加另一个变量,例如 targetIndex。
我目前正在编写一个小轮换程序。但是我在处理 "this is a test" 这样的字符串时遇到了麻烦。当我有这样一个字符串时,它只对前 4 个字符而不是整个字符串进行编码。似乎空格正在破坏某些东西。我试图用 if 语句忽略空格,但这不起作用,我也不知道为什么。你知道这个问题吗?
是的...代码是非常实验性的所以请不要对 const 数组大小和类似的东西生气..
#include <stdio.h>
#include <stdlib.h>
#define alphabetsize 26
char alphabet[alphabetsize] = {'a','b','c','d','e','f','g','h','i','j',
'k','l','m','n','o','p','q','r','s','t',
'u','v','w','x','y','z'};
char lookup[alphabetsize] = {'0'};
char target[100] = {' '};
int search(char ch){
int i = 0;
for( ; i < alphabetsize; i++){
if(alphabet[i] == ch) return i;
}
}
char* rotate(char string[], int rotn){
int i = 0;
for( ; i < alphabetsize ; i++){
lookup[rotn] = alphabet[i];
rotn++;
if(rotn == (alphabetsize)) rotn = 0;
}
i = 0;
int index = 0;
for( ; i < 100; i++){
printf("%d\n", i );
if(string[i] != ' '){
index = search(string[i]);
target[i] = lookup[index];
}
}
printf("%s\n", target);
return target;
}
int main(int argc, char *argv[]){
int rotn = strtol(argv[2], NULL, 10);
printf("String: %s\n", argv[1]);
printf("Used Rotation degree: %d\n", rotn);
char* string = rotate(argv[1], rotn);
printf("Decrypted/Encrypted String: %s\n", string);
return 0;
}
这不能解决您的代码问题,并且是一个代码示例,由于其混淆可能不会让您获得好成绩,但您必须意识到 'rotN' 类型的问题如果您了解 ASCII 字符集的布局,则可以通过模块化数学轻松解决...
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char* rotate(char *s, int rotn)
{
char *s1=s;
for(;*s!='[=10=]'; s++) if(isalpha(*s))
*s = ((*s>'Z')?'a':'A')+(((*s-((*s>'Z')?'a':'A'))+rotn)%26);
return s1;
}
int main(int argc, char *argv[])
{
int rotn = strtol(argv[2], NULL, 10);
printf("String: %s\n", argv[1]);
printf("Used Rotation degree: %d\n", rotn);
char* string = rotate(argv[1], rotn);
printf("Decrypted/Encrypted String: %s\n", string);
return 0;
}
您的部分问题出在 search
,如果在 alphabet
中找不到 ch
,则无法 return 值。实际上,这意味着它将 return 一个未知值,然后您可以在不进行任何检查的情况下使用它来索引 lookup
数组。
根据内存的随机内容,您可以在 target
数组中插入空格或 NUL
个字符。
这实际上是由您的 rotate
函数触发的,该函数不会检查输入字符串中是否存在 NUL
并且不会在字符串末尾终止。
测试
if(string[i] != ' ')
允许在输入字符串中使用不可避免的 NUL
来调用 search
。然后您继续使用随机值调用搜索另外八十次左右 - 其中大部分不太可能在 'a'...'z'
一旦您使用非小写字符调用 search
,您的程序就会进入未定义行为的世界。
最后,正如@gaemaf 所提到的,循环中的输出索引需要独立于输入索引i
。当您跳过输入中的空格时,您也会提前输出指针(因为您对两者都使用 i
)。
初始化target[100] = {' '}
只初始化数组的第一个位置。其余部分包含二进制零,printf
in main
插入为字符串的结尾。因此,即使您旋转整个字符串,也只会打印出第一个单词。
要进行测试,请尝试输入字符串 "a bc def"。我怀疑你只会打印出一个字符。
我发现了你的问题,请尝试告诉我:
在旋转函数中更改您的 for:
int targetIndex = 0;
for (; i < 100; i++){
printf("%d\n", i);
if (string[i] != ' '){
index = search(string[i]);
target[targetIndex++] = lookup[index];
}
}
否则,因为您的目标被初始化为 NULL,您将永远看不到完整的结果。 要解决您的问题,您需要添加另一个变量,例如 targetIndex。