【问题标题】:In C, how to store two char characters from two char arrays into an integer array在C中,如何将两个char数组中的两个char字符存储到一个整数数组中
【发布时间】:2019-06-20 23:49:53
【问题描述】:

我需要从两个不同的 char 数组中获取字符,将它们连接(而不是相加)在一起并将它们存储到相关的 int 数组索引中。然后,我需要在调用该索引时将 ASCII 值显示为两个字符放在一起。例如,我在一个 char 数组中有“4”,在另一个 char 数组中有“A”。然后我希望将“A4”存储到 int[5] 中。当我调用 int[5] 时,我想看到“A4”。

以下是我目前尝试过的。

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


    short cards[52];
    char faces[] = {'A','1','2','3','4','5','6','7','8','9','J','Q','K'};
    char suit[] = {'S','D','H','C'};

    for(int i = 0; i<52;i++){
        if(i<14){
            cards[i] = (char)(10*(suit[0] - '0')+ faces[i] - '0');
        }else if(i<27){
            cards[i] = (char)(10*(suit[1] - '0')+ faces[i-14] - '0');
        }else if(i<40){
            cards[i] = (char)(10*(suit[2] - '0')+ faces[i-27] - '0');
        }else if(i<53){
            cards[i] = (char)(10*(suit[3] - '0') + faces[i-40] - '0');
        }
    }

    printf("%c", cards[5]);
}

【问题讨论】:

  • 啊,作业。我认为这个问题需要一个字节的转变。
  • 我希望将“A4”存储到 int[5] 中。当我调用 int[5] 时,我想看到“A4”。 -- 你说的是cards,它的类型是short [52],而不是“int”,因此 不能“存储'A4'”,而只能是short 整数值。在谈论代码时,表达的准确性很重要。调用printf( "%c", ... ) 需要int 参数,而不是short,并将其转换为unsigned char,丢失您宝贵的西装/面部“编码”并打印单个字符。你在10*(suit[0] - '0' ) 那里所做的事情在几个层面上也是错误的。
  • 投票结束,“不清楚你在问什么”。也许退后一步,问一个关于你真正想要达到的目标的问题——你已经很纠结已经在尝试something了,对于this的任何答案> 问题必须先解开
  • 关于为什么您的西装/面孔编码不起作用的更多提示。 suit[0]'S''S' - '0' 是 35...,乘以 10,是 350,超过了您可以存储在 char 中的最大值,这就是您将结果转换为的值(在存储之前short 数组...)。无论您编写该代码时的想法是什么,它都没有按预期工作。
  • 您是否看到您得到的答案基本上是如何告诉您放弃所有代码并尝试不同的方法?这是不清楚的——你描述的目标与你发布的代码完全不符。一个完整的答案必须解决您完全损坏的代码您真正想要实现的目标。这就是为什么我 - 无意冒犯你,因为你是新来的 - 认为这是一个糟糕的问题,并投票结束这个问题,这样你就可以写出一个更好、更清晰的问题。

标签: c arrays char type-conversion int


【解决方案1】:

如果按照@Govind Parmar 的建议进行,这种方法肯定是简化的。但是,如果您决定将卡片的花色和价值存储在一个短变量中,则可以通过以下方式实现。

这里使用除法的余数(模数)13 来索引人脸数组,用整数除以 13 来索引西装数组。花色首先存储在卡片数组中。然后字节左移。因此花色的值存储在高字节中(假设短是 2 个字节)。字节的大小由limits.h 中的CHAR_BIT 确定。然后使用相应的面(值)数组执行按位或。要打印,您必须将短的右移一个字节以打印西装,然后用 0 屏蔽高字节(使用 0xFFu)以获得面值。

同样,不知道你为什么要这样做,但你可以。

#include <limits.h>
#include <stdio.h>

int main(void) {


    unsigned short card[52] = {0};

    unsigned char faces[] = {'A', '2', '3', '4', '5', '6', '7', '8', '9', '1', 'J', 'Q', 'K'};
    unsigned char suit[] = {'S', 'D', 'H', 'C'};

    for(int i = 0; i < 52; i++) {

        card[i] = suit[i/13];
        card[i] = card[i] << CHAR_BIT;
        card[i] = card[i] | faces[i%13];
    }

    printf("%c%c", card[5] >> CHAR_BIT, card[5] & 0xFFu);
}

【讨论】:

    【解决方案2】:

    我猜sizeof(short)==2 在你的系统上,你的字符集是 ASCII,你相信你可以用你的花色和卡片的数值并排填充短数组,没有任何问题。

    继续进行这些假设,您的代码有以下问题:

    suit[x] - '0'
    

    这是将表示数字的 ASCII 字符转换为数字的数值的正确方法。但是,套装中的值是'S', 'H', 'D','C',所以这是行不通的。

    (suit[0] - '0')+ faces[i]-'0'
    

    这不会在cards[i] 中创建一个值为“&lt;suit-value&gt;&lt;card-value&gt;”的表示,每个char 填充short 的一半。它将创建一个具有suit[0] - '0' + faces[i] - '0' 数值的char

    printf("%c", cards[5]);
    

    打印出short 的正确格式是%hd

    另外,如果您要模拟一副标准扑克牌,faces 中的“10”牌的价值在哪里?

    这就是我粗略浏览一下您的代码所能指出的全部内容。

    我的建议是将组合的花色/面卡表示为字符串,而不是shorts。将cards 更改为char[52][3] 的数组,将其初始化为零,然后创建一个循环通过facessuit 并使用snprintf 之类的字符串构建函数填充cards

    【讨论】:

    • 请不要推荐无限的sprintf,尤其是因为“S10\0”是四个字符。
    • @DavisHerring 如果我想在单个字符中使用字母“T”来表示 10
    • 我可能会使用0。我的观点是固定的弦长很容易出错,所以最好避免将初学者引导到那个方向。
    • @DavisHerring:出于安全考虑,推荐snprintf()sprintf() 更好,并且只有在您实际检查返回值时才进行一些批判性思考......
    • @DevSolar:即使您忽略它,它也不是(本身)未定义的行为,这是一些事情(在安全环境中可能很多)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    • 2012-01-23
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 2019-06-12
    相关资源
    最近更新 更多