将数值变量视为文本

Treating numerical variables as text

我不知道怎么给这个问题起标题,所以我直接上代码让你明白我的意思。真的很新,所以请多多包涵!

我有这个代码:

1   #include <cs50.h>
2   #include <stdio.h>
3   #include <string.h>
4
5   int main(int argc, string argv[])
6   {
7 
8   if (argc!=2)
9   {
10     printf("error!! Usage: ./caesar k\n");
11     return 1;
12   }
13
14   printf("Plaintext: ");
15   string text=get_string();
16 
17   char k=argv[1][0];
18   int n=strlen(text);
19 
20 
21   for (int i=0; i<n; i++)
22   {
23     if(text[i]>='a' && text[i]<='z')
24     {
25         printf("Cyphertext: %c\n", text[i]+k);
26     }
27   }
28   }

它的用途是什么? 好吧,给定一个文本,它将 k 添加到每个字符。这意味着,对于 abck=1,输出将是 bcd;对于 abck=3,输出将是 def.

现在,必须将 k 作为命令行参数给出。

我想做什么? 只需取 k(这是一个数字),将其添加到输入 string text 的每个字符,然后就可以了。 由于每个字母都是 ASCII 中的一个数字,添加一个数字可以改变字符,所以......它应该可以工作。 [我仍在尝试弄清楚 ASCII 是如何工作的,以及 char 何时会像字符而不是数字一样出现...但无论如何]。

这是怎么回事? 首先,我无法将 k 声明为 intchar。在第 17 行,- 尽管 k 是一个数字(!)- IDE 强制我声明一个字符串或 char*:如果我将 k 声明为 int 我收到错误;如果我声明 char,我也会收到一个错误,除非我不仅将其声明为 k=argv[1],而且还声明为 k=argv[1][0],如上面的代码所示。

其次,执行上面的代码,这是输入/输出(程序名是caesar):

$./caesar
error!! Usage: ./caesar k

$./caesar 1
Plaintext: a
Cyphertext: (nothing...)

第三,鉴于上面的错误,我把第25行的代码改成了这样:

printf("Cyphertext: %c\n", text[i]+k);

对此:

printf("Cyphertext: %s\n", text[i]+k);

返回此错误消息:

caesar.c:25:38: error: format specifies type 'char *' but the argument has 
type 'int' [-Werror,-Wformat]
        printf("Cyphertext: %s", text[i]+k);
                            ~~   ^~~~~~~~~
                            %d`

错误消息我不明白,因为 textk 都不是 int

无论如何,将 %c 更改为 %s 没有用,所以我尝试使用 %i 代替:

printf("Cyphertext: %i\n", text[i]+k)

至少返回了一些东西:

$./caesar 1
Plaintext: a
Cyphertext: 146

$./caesar 5
Plaintext: a
Cyphertext: 150

所以,基本上,它是将 k 添加到 150 - 这是 ASCII 中的 'û',所以...(?).

最后,除了程序returns一个我不明白的数字,我想我可以让它显示成letters/non-numerical ] 字符添加:

printf("Cyphertext: %i\n", (char)text[i]+k);

但实际上并没有,程序returns与上面显示的最后一个输出完全相同。

好吧,这个问题比我预期的要长得多,但我希望这里有人有耐心和熟练地回答它。

非常感谢!

如果您只想将数字 ('0'-'9') 转换为数字,只需从输入中减去 '0' 的 Ascii 码即可。

char digit;
int num = digit - '0';

您应该先检查您的输入是否在范围内。

if (digit < '0' || '9' < digit)
    //  error!!

命令行参数总是作为字符串传入。仅仅因为您的程序希望第一个参数看起来像一个数字并不一定意味着传入了一个数字。

因此,当您通过 argv[1][0] 获取字符串中的第一个字符时,您获取的不是值 1,而是 字符 1。假设 ASCII 用于字符,此字符的 ASCII 值为 49。因此 k 在本例中的值为 49。

您需要将参数转换为数字。您可以为此使用 atoi 函数:

int k = atoi(argv[1]);

通用解决方案是

int k = atoi(argv[1]);

atoi 接受一个字符串并将其转换为数字。上面的减法解决方案只处理个位数,这将允许 k > 9