我一直试图想出一个加密字符串的代码。我已多次跟踪此代码但无法找到错误。它只加密第一个单词而在第二个单词失败。
我这样做是为了感叹号是终结者。你能帮忙吗?
char word[50];
int i;
char str[50];
char c;
printf("enter word to decrypt: ");
scanf("%s", word);
for( i = 0; i < 50; i++) {
c = word[i];
if (c == ' ') {
str[i] = c;
continue;
}
if (c == '!') {
str[i] = '\0';
break;
}
str[i] = word[i] + 1;
}
printf("Encrypted string is '%s'\n", str);
答案 0 :(得分:4)
你的意思是你给两个(或更多)单词作为单个scanf
电话的输入吗?那就行不通了。
scanf
"%s"
格式只能读取单个空格分隔的字词。它无法使用"%s"
格式读取多个以空格分隔的单词。
使用循环读取多个单词,或使用fgets
读取整行,或使用不会在空格处停留的格式(例如"%["
)。
您展示代码时还存在其他问题。如果输入超过49个字符的单个单词,它可能会溢出缓冲区。并且循环不关心单词的实际长度,并且将进入数组word
的未初始化的内存中。这两种情况都会导致未定义的行为。
答案 1 :(得分:1)
scanf("%s", word);
会在遇到空格时停止读取字符串。
使用scanf("%49[^\n]", word);
(这不包括换行符)或fgets(word, sizeof(word), stdin);
(这将包括换行符,如果存在)来读取整行。请注意,指定要读取的最大长度对于避免缓冲区溢出非常重要。
另一种解决方案是使用getchar()
直接将字符读取到c
。请注意,将getchar()
返回的内容直接分配给类型为char
的变量是不好的,因为它会阻止EOF
与字符区分。
int i;
char str[50];
char c;
printf("enter word to decrypt: ");
scanf("%s", word);
for( i = 0; i < 50; i++) {
int input = getchar();
if (input == EOF) {
str[i] = '\0';
break;
}
c = input;
if (c == ' ') {
str[i] = c;
continue;
}
if (c == '!') {
str[i] = '\0';
break;
}
str[i] = input + 1;
}
str[49] = '\0'; /* prevent it from accessing out-of-range for in case the input is too long */
printf("Encrypted string is '%s'\n", str);
答案 2 :(得分:1)
第一个问题在这里,我可以看到处于循环状态。您尝试使用固定数量的迭代,例如
for( i = 0; i < 50; i++) {
c = word[i];
现在,如果word
的输入小于50
,而word
是自动本地数组变量,则其余元素的内容将是不确定的。尝试读取该值会调用undefined behavior。
读取输入后,您可以使用strlen()
确定有效索引,并仅读取有效索引中的内容。
所以,总是初始化你的局部变量。
其次,您假设输入字将包含!
字符,您依赖于该字符终止。如果输入没有!
,则字符串没有空终止符,如果以后用作字符串,可能会导致由于内存溢出导致undefined behavior。
最后,正如其他人已经指出的那样,如果您希望%s
将带有空格的句子扫描到word
好吧,%s
与scanf()
一起使用时不起作用。您可能希望使用fgets()
。