我正在写一个程序。传入的字符串就像这个*H1W000500
,这是一个合法的字符串,我将*H1W
之后的字符串内容复制到整数类型。
但是如果字符串不合法,我想过滤掉这个字符串。例如000500
或*H1W.....
,如果字符串不合法,请不要复制内容并跳过。如果字符串是合法的,则仅复制内容。
这里我正在做什么,但每当有不相关的字符串时,它会复制零值,这是不可取的。
*H1W~@#$
答案 0 :(得分:1)
您已接近,但使用strstr
可以更好地表达您对strncmp
的使用情况,以便比较4
的第一个receiveddata
字符。 (如果您的目标字符串位于receiveddata
的中间,那么strstr
就可以了)您还需要对strtoul
转换提供错误检查。将这些部分放在一起你可以做类似下面的事情(注意:这是针对单个值显示的,在循环中,如评论中所述,将return
更改为continue
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
/* declare constants, avoid magic number use in code */
enum { PRE = 4, BASE = 10, MAX = 50 };
int main (void) {
char receiveddata[MAX] = "*H1W000500", *p = NULL;
unsigned long head1weight;
if (strncmp (receiveddata, "*H1W", PRE) != 0) /* cmp 4 chars */
return 1; /* you would continue here */
if (strlen (receiveddata) <= PRE) /* more chars exist? */
return 1; /* you would continue here */
errno = 0; /* set errno to known value */
head1weight = (unsigned)strtoul (&receiveddata[PRE], &p, BASE);
/* check for error conversions on conversion */
if ((errno == ERANGE && (head1weight == ULONG_MAX)) ||
(errno != 0 && head1weight == 0)) {
perror ("strtoul");
return 1; /* you would continue here */
}
if (&receiveddata[PRE] == p) { /* check if chars converted */
fprintf (stderr, "No digits were found\n");
return 1; /* you would continue here */
}
printf ("head1weight : %lu\n", head1weight);
return 0;
}
示例使用/输出
$ ./bin/parsetounsigned
head1weight : 500
仔细看看,如果您有其他问题,请告诉我。
(注意:C通常避免使用MixedCase
和camelCase
变量名来支持所有小写,保留所有大写以用于常量和宏。它是样式,所以这完全取决于你......)
答案 1 :(得分:0)
来自strtoul上的Linux手册页。
如果根本没有数字,strtoul()将nptr的原始值存储在* endptr中(并返回0)。
因此,如果在strtoul
之后,ptr
与起始指针相同,则表示没有合法字符。
char* ptr;
unsigned long Head1Weight = strtoul(p + 4, &ptr, 10);
if (ptr == p + 4)
{
// There were no digits
}
else if (strlen(ptr) > 0)
{
// There were characters in the string after the end of the number
}
答案 2 :(得分:0)
OP的p = strstr(ReceivedData, "*H1W"); if(p) {
在通过strstr("abcd12*H1W", "*H1W")
时不够,虽然它是一个开始。
OP的验证目标不够具体。 “* H1W之后的字符串内容,即000500到整数类型。”
“+ 123”,“ - 123”,“123”评估为整数,是否有效?
“123”可以评估为整数,是否有效?
示例暗示数字部分应该正好是6位小数,但这是不确定的。
示例代码使用unsigned
,可能是16位吗?只有“000000”到“065535”有效吗?
“ - 123”通过strtoul()
转换成功,对此目标有效吗?
这应该通过“* H1W000500xyz”吗?是允许还是忽略额外的文字?
这是编写代码中的常用,因为规范最初有解释问题,然后趋于发展。
代码应该允许进化。
让我们从*H1W
开始,接着是sscanf()
的正好6位小数。检查数字后,下面的代码使用"%n"
来记录扫描位置。如果PREFIX
包含%
,则此方法需要额外的工作。
// PREFIX should not contain %
#define PREFIX "*H1W"
#define DIGIT_FMT "%*[0-9]"
#define VALID_LENGTH 10
char ReceivedData[50];
unsigned long Head1Weight = 0;
int n = 0;
sscanf(ReceivedData, PREFIX DIGIT_FMT "%n", &n);
if (n == VALID_LENGTH && ReceivedData[VALID_LENGTH] == '\0') {
Head1Weight = strtoul(ReceivedData + sizeof PREFIX - 1, NULL, 10);
}