C 函数strtoul不';无法读取完整字符串

C 函数strtoul不';无法读取完整字符串,c,C,我正在创建一个程序,将日期输入为XX/XX/XXXX,并将其输出为月、日、年。 我将日期作为字符串输入,并使用strtoul从中获取一个数字。在找到非数字字符后,函数停止读取并返回一个值,但当我没有包含任何斜杠时,程序工作 // inputs date as string in format "XX/XX/XXXX" // and outputs date in format "MONTH XX, XXXX" #include <stdio.h>

我正在创建一个程序,将日期输入为XX/XX/XXXX,并将其输出为月、日、年。 我将日期作为字符串输入,并使用strtoul从中获取一个数字。在找到非数字字符后,函数停止读取并返回一个值,但当我没有包含任何斜杠时,程序工作

// inputs date as string in format "XX/XX/XXXX"
// and outputs date in format "MONTH XX, XXXX"
#include <stdio.h>
#include <stdlib.h>
#define SIZE 11

void displayDate(unsigned long int dateNum);

int main(void)
{
    char dateString[SIZE]; // initialize input string
    
    printf("%s", "Input a date in format XX/XX/XXXX: ");
    fgets(dateString, SIZE, stdin); // get date string
    
    char *datePtr; // char pointer
    
    unsigned long int dateNum = strtoul(dateString, &datePtr, 0);
    
    printf("%lu", dateNum);
        
    // call function to display date
    // in different format
    displayDate(dateNum); 
}   

void displayDate(unsigned long int dateNum)
{
    unsigned long int month = dateNum / 1000000; // calculate month
    
    unsigned long int day = (dateNum % 1000000) / 10000; // calculate day
    
    unsigned long int year = dateNum % 10000; // calculate year
    
    // ensure valid date
    // otherwise display "Invalid date."
    if (month > 0 && month < 13 && day > 0 && day < 32) {
        // switch prints month
        switch (month) {
            case 1:
                printf("%s", "January");
                break;
            case 2:
                printf("%s", "February");
                break;
            case 3:
                printf("%s", "March");
                break;
            case 4:
                printf("%s", "April");
                break;
            case 5:
                printf("%s", "May");
                break;
            case 6:
                printf("%s", "June");
                break;
            case 7:
                printf("%s", "July");
                break;
            case 8:
                printf("%s", "August");
                break;
            case 9:
                printf("%s", "September");
                break;
            case 10:
                printf("%s", "October");
                break;
            case 11:
                printf("%s", "November");
                break;
            case 12:
                printf("%s", "December");
                break;
        }
        
        // printf statement prints remainder of date
        printf(" %lu, %lu\n", day, year);
    }
    else {
        puts("Invalid date.");
    }
}
//以字符串形式输入日期,格式为“XX/XX/XXXX”
//并以“XX月,XXXX”格式输出日期
#包括
#包括
#定义尺寸11
void displayDate(未签名的长整型dateNum);
内部主(空)
{
char dateString[SIZE];//初始化输入字符串
printf(“%s”,“输入格式为XX/XX/XXXX:”)的日期;
fgets(dateString,SIZE,stdin);//获取日期字符串
char*datePtr;//字符指针
无符号长整型dateNum=strtoul(dateString和datePtr,0);
printf(“%lu”,dateNum);
//调用函数来显示日期
//以不同的格式
显示日期(dateNum);
}   
void displayDate(无符号长整型dateNum)
{
unsigned long int month=dateNum/1000000;//计算月份
无符号长整日=(dateNum%1000000)/10000;//计算日
unsigned long int year=dateNum%10000;//计算年份
//确保有效日期
//否则显示“无效日期”
如果(月>0&&month<13&&day>0&&day<32){
//开关每月打印一次
开关(月){
案例1:
printf(“%s”、“一月”);
打破
案例2:
printf(“%s”、“二月”);
打破
案例3:
printf(“%s”、“三月”);
打破
案例4:
printf(“%s”、“四月”);
打破
案例5:
printf(“%s”、“May”);
打破
案例6:
printf(“%s”、“六月”);
打破
案例7:
printf(“%s”、“七月”);
打破
案例8:
printf(“%s”、“八月”);
打破
案例9:
printf(“%s”、“九月”);
打破
案例10:
printf(“%s”、“十月”);
打破
案例11:
printf(“%s”、“11月”);
打破
案例12:
printf(“%s”、“12月”);
打破
}
//printf语句打印日期的剩余部分
printf(“%lu,%lu\n”,日,年);
}
否则{
放入(“无效日期”);
}
}

您可以简单地执行以下操作:

#include<stdio.h>
#include<stdlib.h>
#include<err.h>

int
main(int argc, char **argv)
{
        unsigned long month, day, year;
        char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "June",
                "July", "August", "Sept", "Oct", "Nov", "Dec" };
        char *k;
        if( argc < 2 ){
                errx(1, "missing date.  Enter in form mm/dd/yyyy");
        }
        month = strtoul(argv[1], &k, 10);
        if( *k != '/' ){
                errx(1, "Invalid format");
        }
        day = strtoul(k + 1, &k, 10);
        if( *k != '/' ){
                errx(1, "Invalid format");
        }
        year = strtoul(k + 1, &k, 10);
        if( *k != '\0' ){
                errx(1, "Invalid format");
        }
        if( month > 0 && month < 13 ){
                printf("%s %lu, %lu\n", months[month - 1], day, year);
        } else {
                errx(1, "Invalid date");
        }
        return EXIT_SUCCESS;
}
#包括
#包括
#包括
int
主(内部argc,字符**argv)
{
未签名的长月份、天、年;
字符*月份[]={“一月”、“二月”、“三月”、“四月”、“五月”、“六月”,
“七月”、“八月”、“九月”、“十月”、“十一月”、“十二月”};
char*k;
如果(argc<2){
errx(1,“缺少日期。以mm/dd/yyyy格式输入”);
}
月=strtoul(argv[1],&k,10);
如果(*k!='/')){
errx(1,“无效格式”);
}
日=strtoul(k+1和k,10);
如果(*k!='/')){
errx(1,“无效格式”);
}
年份=标准(k+1和k,10);
如果(*k!='\0'){
errx(1,“无效格式”);
}
如果(月份>0和月份<13){
printf(“%s%lu,%lu\n”,月[月-1],日,年);
}否则{
errx(1,“无效日期”);
}
返回退出成功;
}

我忘了发布这个函数,但我只调用了三次该函数,分别获取月、日和年,并在每次调用之间递增datePtr。

。。有什么问题?这就是
strtoul
的工作定义。strtoul在找到非数字后停止读取?那么,我可以一次发送几个字符串索引吗?@WeatherVane它在某种意义上是有效的:“如果基数为0或16,字符串可能会包含一个“0x”前缀,数字将以16为基数读取;否则,除非下一个字符是“0”,否则零基数将被视为10(十进制),在这种情况下,它将被视为8(八进制)。”请阅读文档。它回答了你所有的问题。“字符串的其余部分以明显的方式转换为无符号长整型值,在给定基中不是有效数字的第一个字符处停止”如果是,我将创建一个替换斜杠的循环-您不需要这样做,函数有一个选项为您提供指向第一个非数字的指针。因此,您可以递增并将其传递给下一个
strtoul
调用。