我需要编写一个函数,该函数将检查字符串的一些属性:
如果满足这些条件,则应以int形式返回字符串,如果不满足任何条件,则应返回-1。
当前,该函数无法处理以下2个输入:
4y
13.4
如果我的isDigit()
循环按预期工作,则可以检查它们。为什么循环不起作用?
int convert(const char length[]) {
long input = atol(length);
if (input >= 2147483648 || input <= 0) {
return -1;
}
int chkr = 0;
while (chkr < strlen(length)) {
if (isdigit(length[chkr++]) == 0) {
return -1;
}
else {
return atoi(length);
}
}
input = atol(length);
if (length[0] == '0') {
return -1;
}
if (strlen(length) < 3) {
return -1;
}
else {
return atoi(len gth);
}
}
答案 0 :(得分:1)
您的函数非常复杂且错误。
改为使用此代码,然后让C库完成肮脏的工作:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
// The function you're interested in
int convert(const char string[]) {
char *endptr;
if (!isdigit((unsigned char)string[0]))
return -1;
errno = 0; // need to set errno to 0 (see errno documentation)
long value = strtol(string, &endptr, 10);
if (errno != 0 || value <= 0 || value > 2147483647 || *endptr != 0)
{
return -1;
}
return value;
}
int main() {
// Test different cases:
struct {
const char *input;
int expected;
} testcases[] =
{
// OK cases
"123", 123,
"1234", 1234,
"2147483647", 2147483647,
// fail cases
"-1234", -1, // number is negatif
"12.3", -1, // contains non digit '.'
"123y", -1, // contains non digit 'y'
"2147483648", -1, // out of range
" 123", -1, // starts with a space
// wrong test case on purpose
"1234", 1245,
};
// Test all test cases
for (int i = 0; i < sizeof(testcases) / sizeof(testcases[0]); i++)
{
int value = convert(testcases[i].input);
if (value != testcases[i].expected)
{
printf("convert(\"%s\") failed, returned value = %d, expected value = %d\n", testcases[i].input, value, testcases[i].expected);
}
else
{
printf("convert(\"%s\") passed\n", testcases[i].input);
}
}
return 0;
}
程序将打印每个测试用例。最后一个测试用例故意是错误的。
for循环遍历许多测试用例,对于每个失败的测试用例,它将打印涉及的值。
输出:
convert("123") passed
convert("1234") passed
convert("2147483647") passed
convert("-1234") passed
convert("12.3") passed
convert("123y") passed
convert("2147483648") passed
convert("1234") failed, returned value = 1234, expected value = 1245
答案 1 :(得分:0)
您仅检查第一个字符,然后立即返回。
input = atol(length);
无法访问。
答案 2 :(得分:0)
查看此循环:
while (chkr < strlen(length)) {
if (isdigit(length[chkr++]) == 0) {
return -1;
}
else {
return atoi(length);
}
}
您不会遍历整个字符串,反正要在第一个字符之后返回。您不想在此处以else
的形式返回,否则将跳过程序的其余部分。拥有这个:
while (chkr < strlen(length)) {
if (isdigit(length[chkr++]) == 0) {
return -1;
}
}
之后,此行在这里
input = atol(length);
不需要。输入仍然具有该值。但这不会造成任何伤害。
答案 3 :(得分:0)
int convert(const char length[]) {
if (atol(length) >= 2147483648 || atol(length) <= 0)
return -1;
int chkr = 0;
while (chkr < strlen (length)) {
if (isdigit(length[chkr++]) == 0)
return -1;
}
return atoi(length);
}
编辑:固定答案。不知道为什么我不使用isdigit()。
我想太努力了,以至于适得其反。
答案 4 :(得分:0)
如前所述,while
循环在第一次迭代后返回。
使用sscanf
代替atol
或atoi
。这样比较可取,因为您可以检测到错误:
int convert(const char *length){
int err, sz;
unsigned rtn;
/*%u reads an unsigned integer (mostly 32 bit) >= 0*/
err = sscanf(length, "%u%n", &rtn, &sz);
/*check reading error occured*/
if(err == 0){
return -1;
}
/*check if there is no whitespace/sign*/
if(!isdigit(length[0])){
return -1;
}
/*check if 0 < rtn <= INT_MAX*/
if(rtn <= 0 || rtn > INT_MAX){
return -1;
}
/*check everything got read*/
/*=> no letters*/
if(sz != strlen(length)){
return -1;
}
return rtn;
}
让我们测试一下:
/*these fail*/
const char zero[] = "0";
const char spaceStart[] = " 84654";
const char spaceEnd[] = "84654 ";
const char negative[] = "-7869";
const char tooBig[] = "2147483648";
const char fitsInto32BitInt[] = "2147483647";
const char positive[] = "+7526";
const char withLetter[] = "4y";
const char withPoint[] = "13.4";
/*these work*/
const char one[] = "1";
const char fine[] = "746838";
const char fitsInto32BitInt[] = "2147483647";