为什么我不能加密第二个单词?

时间:2016-06-17 14:33:31

标签: c encryption scanf

我一直试图想出一个加密字符串的代码。我已多次跟踪此代码但无法找到错误。它只加密第一个单词而在第二个单词失败。

我这样做是为了感叹号是终结者。你能帮忙吗?

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);

3 个答案:

答案 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好吧,%sscanf()一起使用时不起作用。您可能希望使用fgets()