为什么在 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 的事实是问题所在,但我不知道为什么(不是我真的理解其中的任何一个)
谢谢!
argv
和 argc
和 "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
使用不同的值,包括 0
、1
、'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);
}
首先 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 的事实是问题所在,但我不知道为什么(不是我真的理解其中的任何一个) 谢谢!
argv
和 argc
和 "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
使用不同的值,包括 0
、1
、'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);
}