如何在char数组的特定索引处获取实际值

时间:2014-06-15 21:23:14

标签: c++ arrays

我有一个我正在进行日期验证的程序。我以MM / DD / YYYY的形式收到用户的输入并将其存储为字符数组。

首先,我尝试将其分解为具有强制转换的月份和年份的int变量

 char UserDate[10];
 int month = 00, day = 00, year = 0000;
 cout << "Enter a date in the format of MM/DD/YYYY" << endl;
 cin >> UserDate;
 month = (int)UserDate[0] + (int)UserDate[1];
 day = (int)UserDate[3] + (int)UserDate[4];
 year = (int)UserDate[6] + (int)UserDate[7] + (int)UserDate[8] + (int)UserDate[9];

然后我尝试了它而没有投射

 char UserDate[10];
 int month = 00, day = 00, year = 0000;
 cout << "Enter a date in the format of MM/DD/YYYY" << endl;
 cin >> UserDate;
 month = UserDate[0] + UserDate[1];
 day = UserDate[3] + UserDate[4];
 year = UserDate[6] + UserDate[7] + UserDate[8] + UserDate[9];

问题是我无法从数组的索引中获取实际值。 我输入的日期01/01/2014的结果如下:

month = 48'0' + 49'1'; //months value is 97
day = 48'0' + 49'1'; //days value is 97
year = 50'2' + 48'0' + 49'1' + 52'4'; //years value is 199

对于上述两种方法,无论我是否将char转换为int,都会发生这种情况。如何获取存储在我想要的索引中的值,因为没有UserDate[1].Value ??

3 个答案:

答案 0 :(得分:3)

Casting不会将char转换为int。减去'0'以获得int值。

month = 10 * (UserDate[0] - '0') + UserDate[1] - '0';

答案 1 :(得分:1)

您的UserDate数组实际上是一个字符数组,每个字符由一个标准ASCII代码表示(请参阅完整的ASCII表here)。像你一样使用显式转换会导致将char(无论是字母还是数字)转换为整数ASCII代码。例如 - 角色&#39; 0&#39; ASCII值为48,因此写(int)'0'等于48。

由于数字0-9在ASCII表中按顺序出现,因此您可以通过编写以下内容来评估每个字符:

int digit = (int)UserDate[...] - '0'

这里的数学非常简单,所以我相信你能理解为什么这是真的。

请注意,如果您的字符不是数字,则此转换将产生负整数或大于9的数字,因此您应检查您收到的值是否有效。

答案 2 :(得分:0)

您遇到的问题是C不会以这种方式将字符转换为数字。 char是1个字节的数字。除非您在代码中明确指定,否则char是有符号还是无符号取决于您的编译器。如果我这样做:

char x = '1';
int y = (int)x;

我实际上在我的编译器和我的平台上有y = 49。这是字符1的ASCII值,对于本讨论的目的,它可能与其他人不同(具体来说,如果我使x成为无符号字符我可能没问题,并且1的ASCII值很低)足以让它无论如何)。除非你知道自己在做什么,否则不要认为字符会保留特定值。有些人将它们用作小整数,如果你理解ASCII,你可以做一些技巧。在我看来,这些最好隐藏在图书馆中或仅在非常特殊的情况下使用。

其次,你不能只添加演员值:即使假设演员阵容有效,你还要为1999年添加数字,你的方法会给出28分。因为它没有,你得到的是字符串那部分的ASCII值之和。如果你想要+连接字符串,你必须使用std::string来处理所有事情。否则,字符基本上是1字节整数。

如果您绝对肯定该字符串有效,则可以执行以下操作。如果它无效,则会中断,因此您需要验证字符串。这是一个演示该技术的程序。这不是最好的编码实践:你应该使用std :: string,使parseDate成为构造函数,并做一些其他的事情。我以一些优秀的设计实践为代价,故意保持这种简单。实际上,我建议寻找一个日期处理库:boost.date_time不是我用过的东西,但根据我对boost的其他部分的经验将使它成为我的第一选择。你最终会需要更多的功能,除非这是一个非常小的项目,为什么重新发明轮子?总之:

#include <stdio.h>

class date {
    public:
    int day, month, year;
};

date parseDate(const char* str) {
    date d;
    sscanf(str, "%i/%i/%i", &d.month, &d.day, &d.year);
    return d;
}

void main() {
    char test[255];
    scanf("%s", &test);
    date d = parseDate(test);
    printf("%i %i %i", d.day, d.month, d.year);
}

请注意,至少在我看来,sscanfscanf实际上在很多方面比cincout更强大 - 对于这种解析特别是,如果没有引入外部库,它们几乎总是我的首选。既然你已经使用了char数组(这是不安全的,你应该使用std :: string),你不需要额外的转换。如果需要将std :: string传递给它,请使用std :: string :: c_str(),如:

string dateString;
cin>>dateString;
date d = parseDate(dateString.c_str());

希望这有帮助。