只读c中复杂字符串的整数

我试图只读取字符串中的整数。 每次迭代时,空格和非整数字符基本上是随机的。 理想情况下,我的代码将遍历此代码并仅打印(或以其他方式存储)整数。 所以对于这个测试用例,它将是6,1,0,16,2,3等等。

 char line [ 200 ] ="T06 1/ 0 16/ 2 3/15 41/40 17/36 0/11 0/11 0/11 1/14 1/ 7"; int num=0; int count=0; int i=0; char *str = line; while (sscanf(str, "%d%n", &num,&i)){ printf ("number: %d\n",num); str+=i; count++; } 

显然它不起作用,我想我需要一种方法让sscanf跳过任何不是0-9的东西。 有帮助吗?

谢谢

改成

 while (sscanf(str, "%*[^0-9]%d%n", &num, &i)==1){ printf ("number: %d\n",num); str+=i; count++; } 

用空格替换所有非数字字符,然后只scanf它们。 您需要对负片进行调整,但我对此进行了测试,并为给定的输入提供了所需的输出。

 char line [ 200 ] ="T06 1/ 0 16/ 2 3/15 41/40 17/36 0/11 0/11 0/11 1/14 1/ 7"; int num=0; int count=0; int i=0; char *str = line; for (int i = 0; i < strlen(line); i++) if (!isdigit(line[i])) line[i] = ' '; while (sscanf(str, "%d%n", &num,&i) == 1){ printf ("number: %d\n",num); str+=i; count++; } 
 #include  #include  #include  #include  #include  enum oflow { OFL_GOOD, OFL_OVER, OFL_UNDER }; int getnums(const char *str, int nums[], enum oflow oflow[], int n) { int i; for (i = 0; *str; ) { char *junk; long val; str += strcspn(str, "0123456789+-"); if (!*str) break; errno = 0; val = strtol(str, &junk, 10); if (junk > str) { if (i < n) { if (((val == LONG_MIN) && errno == ERANGE) || (val < INT_MIN)) { nums[i] = 0; oflow[i++] = OFL_UNDER; } else if (((val == LONG_MAX) && errno == ERANGE) || (val > INT_MAX)) { nums[i] = 0; oflow[i++] = OFL_OVER; } else { oflow[i] = OFL_GOOD; nums[i++] = val; } } else { i++; } str = junk; } else { str++; /* no number was pulled out: skip one char and try again */ } } return i; } int main(int argc, char **argv) { int nums[256]; enum oflow oflow[256]; if (argc > 1) { int n = getnums(argv[1], nums, oflow, 256); int i; if (n > 256) { printf("array is too small: we need %d elements\n", n); n = 256; } for (i = 0; i < n; i++) { if (oflow[i]) printf("nums[%d] = %sflow\n", i, oflow[i] == OFL_OVER ? "over" : "under"); else printf("nums[%d] = %d\n", i, nums[i]); } } return 0; } 

测试:

 $ ./nums“”
 $ ./nums“0”
 nums [0] = 0
 $ ./nums“ - ”
 $ ./nums“+”
 $ ./nums“+1”
 nums [0] = 1
 $ ./nums“-1”
 nums [0] = -1
 $ ./nums“abc”
 $ ./nums“asd + asdf + 1 -0 + 1-3234abc-10zzz-”
 nums [0] = 1
 nums [1] = 0
 nums [2] = 1
 nums [3] = -3234
 nums [4] = -10
 $ ./nums“+++  -  1 +++”
 nums [0] = -1
 $ ./nums“++”
 $ ./nums“1 + 11111111111111111111111-111111111111111111111”
 nums [0] = 1
 nums [1] =溢出
 nums [2] =下溢
 $ ./nums“$(seq 1 300)”| 头-5
数组太小:我们需要300个元素
 nums [0] = 1
 nums [1] = 2
 nums [2] = 3
 nums [3] = 4
 $ ./nums“$(seq 1 300)”| 尾巴-5
 nums [251] = 252
 nums [252] = 253
 nums [253] = 254
 nums [254] = 255
 nums [255] = 256

家庭作业练习:在strtol之后的什么情况下是junk == str ,以便str++案例执行? 为什么我们需要这个逻辑?

sscanf真的很难用,如果你的输入每次都不一样,那就更糟了。 您可以尝试正则表达式,或者您可能尝试手动解析整数,如下所示:

 int i; int num = 0; int num_valid = 0; int count = 0; for(i = 0; line[i]; i++) { // loop through every character if(line[i] >= '0' && line[i] <= '9') { // check to see if it's a digit num *= 10; // scale up num num += lin[i] - '0'; // convert ASCII to INT num_valid = 1; // indicate that num contains a real number } else if(num_valid) { // if the number is done printf ("number: %d\n",num); count++; num = 0; num_valid = 0; } } 

OP几乎拥有它!

sscanf()添加字符串结尾和返回值表单的测试

 char line [200]="T06 1/ 0 16/ 2 3/15 41/40 17/36 0/11 0/11 0/11 1/14 1/ 7"; int num; int count=0; int i; char *str = line; while (*str) { if (1 == sscanf(str, "%d%n", &num, &i)){ printf ("number: %d\n", num); str += i; count++; } else str++; }