基本上,我的代码应该通过取出所有偶数索引值(从0开始)和奇数索引值并将奇数索引值之前的偶数索引值加密来对句子(或单词)进行加密。 例如,类似“ test”(0)t(1)e(2)s(3)t的单词应打印为(0)t(2)s(1)e(3)t或“ tset”。不应打印任何数字,我只是使用它们来显示奇数和偶数索引值。 我的代码有时可以运行,具体取决于运行的位置。我似乎在代码块和尝试的在线编译器之间得到了不同的结果。我怀疑这种不一致一定是一个更大的问题。谁能帮助我看看我在做什么错,以便我最终能够理解并纠正错误?
我尝试使用一个计数器将偶数和奇数索引值都输入到一个数组中,但是我也遇到了错误,因此我决定将它们放入单独的数组中,然后使用strcat
来组合它们。有没有一种方法可以使其与我在代码中显示的方法一起使用,还是应该回到上一个方法?
#include <stdio.h>
#include <string.h>
#define SIZE 1000
int main()
{
char message[SIZE];
char even[SIZE];
char odd[SIZE];
int length,j=0;
printf("Enter a word or sentence.\n");
fgets(message,SIZE,stdin);
printf("Your message is: %s\n",message);
message[strcspn(message, "\n")] = 0;
length=strlen(message);
printf("The length of the message is: %d\n",length);
for(int i=0;i<length;i+=2){
even[i/2]=message[i];
// printf("%c\n",even[i/2]);
}
for(int i=1;i<length;i+=2){
odd[j]=message[i];
j++;
}
printf("The even letters are: %s\n",even);
printf("The odd letters are: %s\n",odd);
strcat(even,odd);
printf("%s",even);
/*printf("\nFInalyy.");
for(i=0;i<=count;i++)
for(j=i+1;j<=count;j++){
if(strcmp(allmessages[i],allmessages[j])>0){
strcpy(temp,allmessages[i]);
strcpy(allmessages[i],allmessages[j]);
strcpy(allmessages[j],temp);
}
}
printf("The original messages in alphabetical order are: ");
for(i=0;i<=count;i++)
puts(allmessages[i]);*/
return 0;
}
当我输入“ test”或“ sentence”之类的单词时,它可以完美地工作。有时我会输入诸如“这是一个测试句子”之类的句子,它会很好地工作,然后一次它将打印出一些随机垃圾信件以及加密的句子。我想知道如何解决此问题,并想知道为什么它多次与同一个条目完美配合后才停止。我使用https://www.onlinegdb.com/online_c_compiler进行了最后几次测试,因此我的结果基于此。
成功的结果:
使用相同条目的不成功结果:
答案 0 :(得分:1)
您可以根据用户输入的evenstart
的总长度,简单地使用两个索引来构建加密的字符串(例如oddstart
和message
),从而略微缩短方法。 evenstart = 0;
和oddstart = (msglen + 1) / 2;
然后循环遍历用户输入的消息中的字符,这些字符分别写在encrypt[evenstart++]
的偶数字符和encrypt[oddstart++]
的奇数字符。 (如果要将其用作输出字符串,请不要忘记使用 nul-terminate encrypt
。
将其放在一起即可:
#include <stdio.h>
#include <string.h>
#define MAXC 1024
int main (void) {
char message[MAXC],
encrypt[MAXC];
size_t len, evenstart = 0, oddstart;
fputs ("enter message: ", stdout);
if (!fgets (message, MAXC, stdin)) { /* validate message entered */
fputs ("(user canceled input)\n", stdout);
return 1;
}
message[(len = strcspn(message, "\r\n"))] = 0; /* trim '\n', get len */
oddstart = (len + 1) / 2; /* get oddstart (add 1 before divide) */
for (size_t i = 0; i < len; i++) /* loop over each char */
if (i & 1) /* if odd, write char at oddstart */
encrypt[oddstart++] = message[i];
else /* if even, write at evenstart */
encrypt[evenstart++] = message[i];
encrypt[len] = 0; /* nul-terminate */
printf ("message : '%s'\nencrypt : '%s'\n", message, encrypt);
}
(注意:如果需要,您可以使用i % 2
来检查偶数/奇数,如果二进制位是{{ 1}}是奇怪的,否则是偶数-由您决定)
使用/输出示例
i & 1
仔细研究一下,如果您有任何疑问,请告诉我。
答案 1 :(得分:1)
C中的字符串以空字节('\ 0'或ascii值0)终止,只是它知道字符串的结尾。由于偶数和奇数字符数组没有以空字节终止,因此strcat不知道何时停止追加字符。因此,您看到的垃圾值是因为strcat会不断追加字符,直到您幸运地在内存中找到0。
答案 2 :(得分:0)
C中的字符串不知道它们的长度,它们只是指针。字符串必须以空字符结尾,以便printf
和strlen
之类的函数知道何时停止。
char even[SIZE];
char odd[SIZE];
此时even
和odd
都包含当时内存中的所有垃圾。
for(int i=0;i<length;i+=2){
even[i/2]=message[i];
}
for(int i=1;i<length;i+=2){
odd[j]=message[i];
j++;
}
现在odd
和even
的开头已被填充,但它们不是以null结尾的。
printf("The even letters are: %s\n",even);
printf("The odd letters are: %s\n",odd);
这些操作将从even
和odd
指向的位置开始,打印您在其中放置的字符,然后继续打印内存中的所有垃圾,直到碰巧遇到空字符为止。
解决方法是使用memset
将内存清零。
memset(even, '\0', SIZE);
memset(odd, '\0', SIZE);
或者一旦完成对even
和odd
的终止操作,请确保它们为空。
for(i=0;i<length;i+=2){
even[i/2]=message[i];
}
even[i/2] = '\0';
for(i=1;i<length;i+=2){
odd[j]=message[i];
j++;
}
odd[j] = '\0';
旁注even
和odd
循环可以使用相同的技术完成。
for( i=0,j=0; i<length; i+=2,j++ ) {
even[j]=message[i];
}
even[j] = '\0';
for( i=1,j=0; i<length; i+=2,j++ ) {
odd[j]=message[i];
}
odd[j] = '\0';
然后我们可以观察到唯一的区别是我们开始阅读message
的位置。这意味着我们可以将其放在函数中,并始终记住将结果终止为null。
void copy_every_other_character(const char *src, char *dst) {
int i,j,length = 0;
length = strlen(src);
for( i=0,j=0; i<length; i+=2,j++ ) {
dst[j] = src[i];
}
dst[j] = '\0';
}
copy_every_other_character(message, even);
copy_every_other_character(message+1, odd);
在message
上加1表示copy_every_other_character
将获得指向message
的第二个字符的指针,然后从那里继续。如果message
是01234
,它将看到1234
。