为什么在 C 中添加一个 char(来自 argv)会导致 no-result

Why does adding a char (from argv) cause a no-result in C

首先 post(如您所知),表格告诉我我的标题不好,会被否决,但我不能做得更好 :) 我已经为此做了很多工作。

我正在尝试通过将命令行中给定的数字添加到字符串来加密文本。

为什么

include <stdio.h>
int main(int argc, char * argv[])
{
    printf("%i", argc);
    char k = argv[1][0];
    printf("%c", k);
    char * s = "a";
    printf("%c", s[0] + 0);
}

正确打印 "a"(除了打印 argc 和 k) 但是当最后一行是

    printf("%c", s[0] + k);

它只打印 argc 和 k,然后什么都不打印。我想让它打印 20a(当 运行 ./question 0)。

( 我试过了

char k = 0;
char * s = "a";
printf("%c", s[0] + k);

这确实有效:( ) 似乎 k 来自 argv 的事实是问题所在,但我不知道为什么(不是我真的理解其中的任何一个) 谢谢!

argvargc"a" 都是转移注意力的东西。他们与问题无关。问题在于不理解两个字符值 '0'0 之间的区别(后者也称为 '[=16=]')。

为了了解其中的区别,我建议试用此程序:

#include <stdio.h>
int main(void) {
    char a = 'a', b = '0';
    printf ("as char: a=%c b=%c sum=%c\n", a, b, a+b);
    printf ("as int: a=%d b=%d sum=%d\n", a, b, a+b);
}

b 使用不同的值,包括 01'0''1',看看会发生什么。

问题是表达式s[0] + k是一个字母和一个数字相加(从概念上讲,暂时忽略数据类型)很容易得到一个超过末尾的值字母表,并将其打印出来 就好像它是一个字母 不一定可行。

额外的问题:将命令行参数读入单个字符并不是给你一个值 0,而是 '0',它的数值是 48。你不能只取出第一个字符串中的字符。如果用户运行该程序并将 10 作为参数传递怎么办?

您需要确保计算结果在字母范围内。

按照上面评论者的建议,看一下ASCII table,并尝试使用一些字符常量如'a' 'z' 'A''Z'来修改结果

答案很简单。

'a'的ASCII码是97。

假设参数中只有可打印字符,argv 中的最低可打印 ASCII 代码是 32。

97+32 = 整数溢出,这是 UB - 在 ideone.com 系统上是 -127

你可以自己试试 https://ideone.com/D8DLcy

#include <stdio.h>

int main(void) {
    for(char x = 32; x < 127; x++)
    {
        char m = 'a' + x;

        printf("'a' +  %c = char value in decimal is:%hhd - and the char is%c\n", x, m, m);
    }
    return 0;
}

根据您提供的信息,您似乎正在实施一个简单的移位密码。请注意在 k 的输入大于 25 的情况下使用模数。

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>

#define     MAX_STRING  16

int main(int argc, char *argv[])
{
    char        num[MAX_STRING];

    char * s = "a";
    int k;

    if (argc == 2)
    {
        snprintf(num,MAX_STRING, argv[1], 10);

        k = (int)strtol(num, NULL, 10) % 26;

        printf("%c\n", s[0] + k);

    }
    else
    {
        fprintf(stderr,"Invalid number of arguments\n");
        return(EXIT_FAILURE);
    }
    return(EXIT_SUCCESS);
}