[英]Atoi() and strtol() not working correctly in C
基本上我想检查我写的时间是否有效我输入了这个字符串:20:40: 20:40:30
,结果是: No
当我调试问题时,发现atoi
无法正常工作。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main() {
char Input[20] = { '\0' };
scanf("%s", &Input);
char sub1[2] = { '\0' };
char sub2[2] = { '\0' };
char sub3[2] = { '\0' };
strncpy(sub1, Input, 2);
strncpy(sub2, Input + 3, 2);
strncpy(sub3, Input + 6, 2);
int H = atoi(sub1);
int M = atoi(sub2);
int S = atoi(sub3);
int count = 0;
if (H >= 0 && H < 24) count++;
if (M >= 0 && M < 60) count++;
if (S >= 0 && S < 60) count++;
if (count == 3)
printf("Yes);
else
printf("No");
return 0;
}
我也尝试了strtol
,但仍然是同样的问题。
您的代码中有多个问题:
strncpy()
不会在目标中设置 nul 终止符。 使目标 arrays 更长并将其初始化为0
就足以解决这里的问题,但语义strncpy()
令人困惑且容易出错,因此最好避免使用 function。"1x+ 2=3b"
和"abcdefgh"
一样被认为是正确的,因为您只检查从偏移量 0、3 和 6 开始的数字是否在适当的范围内。这是一个更有效的验证:
#include <stdio.h>
#include <stdlib.h>
int main() {
char Input[20], sub1[3], sub2[3], sub3[3];
int pos;
char c;
/* read a string of at most 19 characters */
if (scanf("%19s", Input) != 1) {
printf("No: input error\n");
return 1;
}
/* extract 3 fields of at most 2 digits separated by ':'
* verify that all characters have been consumed
* verify that 8 characters have been consumed
*/
if (sscanf(Input, "%2[0-9]:%2[0-9]:%2[0-9]%n%c", sub1, sub2, sub3, &pos, &c) != 3 || pos != 8) {
printf("No: format error\n");
return 1;
}
int H = atoi(sub1);
int M = atoi(sub2);
int S = atoi(sub3);
/* no need to test for negative values since we already verified
* that the fields have 2 digits
*/
if (H < 24 && M < 60 && S < 60)
printf("Yes\n");
else
printf("No: values out of range\n");
return 0;
}
当达到最大字符数时, strncpy()
不会放置最后'\0'
。
您必须手动放置它,并确保有足够的存储空间。
(当然,如果结果缓冲区已经用零填充,则不必显式放置它,但在一般情况下,您必须确保)
在您的尝试中, atoi()
会在您复制的两个字符之后找到任何内容; 这是一个缓冲区溢出,这个字符序列可能看起来不像 integer。
/**
gcc -std=c99 -o prog_c prog_c.c \
-pedantic -Wall -Wextra -Wconversion \
-Wc++-compat -Wwrite-strings -Wold-style-definition -Wvla \
-g -O0 -UNDEBUG -fsanitize=address,undefined
**/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char Input[20]={'\0'};
scanf("%s",Input);
char sub1[3]={'\0'}; // 2 --> 3 for the final '\0'
char sub2[3]={'\0'}; // note that since these arrays are partially
char sub3[3]={'\0'}; // initialised, they contain some zeros in the
// remaining locations.
strncpy(sub1,Input,2);
sub1[2]='\0'; // useless here since sub1 is filled with zeros
strncpy(sub2,Input+3,2);
sub2[2]='\0'; // useless here since sub2 is filled with zeros
strncpy(sub3,Input+6,2);
sub3[2]='\0'; // useless here since sub3 is filled with zeros
int H=atoi(sub1);
int M=atoi(sub2);
int S=atoi(sub3);
int count=0;
if (H>=0 && H<24)count++;
if (M>=0 && M<60)count++;
if (S>=0 && S<60)count++;
if (count==3)printf("Yes\n");
else printf("No\n");
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.