简体   繁体   English

为什么添加字符(来自argv)导致C无效

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

first post (as you would know) and the form tells me that my title is bad and will get downvoted but I can't do better :) I've worked on this a bunch already. 第一篇文章(如您所知),表格告诉我我的头衔不好,会被低估,但我做不到更好的方法:)我已经做了很多工作。

I'm trying to cipher text by adding a number given in the command line to a string. 我正在尝试通过将命令行中给定的数字添加到字符串来对文本进行加密。

Why does 为什么

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

correctly print "a" (besides for printing argc and k) but when the last line is 正确打印“ a”(除了打印argc和k),但是当最后一行是

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

it just prints argc and k and then nothing. 它只打印argc和k,然后什么也不打印。 I wanted it to print 20a (when running ./question 0 ). 我希望它打印20a (运行./question 0 )。

( I tried ( 我试过了

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

and that does work :( ) It seems like the fact that k is coming from argv is the issue but I don't have any idea why (not that I really understand any of this) Thanks! 并且确实起作用:()似乎k来自argv的事实是问题所在,但我不知道为什么(不是我真的很了解这件事),谢谢!

argv and argc and "a" are all red herrings. argvargc以及"a"都是红色鲱鱼。 They have nothing to do with the problem. 他们与问题无关。 The problem lies in not understanding the difference between two character values, '0' and 0 (the latter is aso known as '\\0' ). 问题在于不了解两个字符值'0'0 (后者也称为'\\0' )之间的区别。

In order to understand the difference I suggest experimenting with this program: 为了理解差异,我建议尝试以下程序:

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

Use different values for b , including 0 , 1 , '0' and '1' and see what happens. 使用不同的值b ,包括01'0''1' ,看看会发生什么。

The problem is that the expression s[0] + k is that adding a letter and a number together (conceptually speaking, ignoring the data types for a minute) can easily result in a value that is past the end of the alphabet, and printing it out as if it was a letter isn't necessarily going to work. 问题在于表达式s[0] + k是将字母和数字加在一起(从概念上讲,一分钟内忽略数据类型)会很容易导致其值超出字母结尾并打印好像是一封信并不一定奏效。

Bonus problem: reading the command line parameter into a single character isn't giving you a value of 0, but '0' which has a numerical value of 48. You can't just pull out the first character from the string. 奖金的问题:读命令行参数到一个单一的字符不是给你的值为0,而'0'拥有的48数值你不能只从字符串拉出第一个字符。 What if the user runs the program and passes 10 as a parameter? 如果用户运行程序并传递10作为参数怎么办?

You need to make sure that the result of your calculation is within the bounds of the alphabet. 您需要确保计算结果在字母的范围内。

As suggested by commenters above, take a look at the ASCII table, and try using some character constants sich as 'a' 'z' 'A' and 'Z' to modify the result 如上述评论者所建议,请看一下ASCII表,并尝试使用一些字符常量sich作为'a' 'z' 'A' a''z''A 'a' 'z' 'A''Z'来修改结果

The answer is very simple. 答案很简单。

The ASCII code of 'a' is 97. ASCII码'a'是97。

Assuming only the printable characters in the arguments, the lowest printable ASCII code from the argv is 32. 假设参数中仅可打印字符,则argv中最低的可打印ASCII代码为32。

97+32 = integer overflow which is UB - on ideone.com system it is -127 97 + 32 =整数溢出,它是UB-在ideone.com系统上是-127

you can try yourself https://ideone.com/D8DLcy 您可以尝试一下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;
}

From the information you provided, it looks like you're implementing a simple shift cipher. 根据您提供的信息,您似乎正在实现简单的移位密码。 Note the use of modulo for cases where the input for k is greater than 25. 请注意,对于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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM