[英]Progress string parsing in C
我有以下字符串:
"..1....10..20....30...40....50...80..."
我需要從中提取所有數字到數組中。
用C做最好的方法是什么?
也許最簡單的方法是使用strtok()
函數(或strtok_r()
如果擔心重入):
char str[] = "..1...10...20";
char *p = strtok(str, ".");
while (p != NULL) {
printf("%d\n", atoi(p));
p = strtok(NULL, ".");
}
一旦得到調用atoi()
的結果,將這些整數保存到數組中應該是一件簡單的事情。
您可以使用帶有抑制分配的sscanf代碼(%* [。])來跳過點(或任何其他所需字符),並使用掃描字符計數代碼%n來推進字符串指針。
const char *s = "..1....10..20....30...40....50...80...";
int num, nc;
while (sscanf(s, "%*[.]%d%n", &num, &nc) == 1) {
printf("%d\n", num);
s += nc;
}
這是正確的方法,它比最簡單的方法稍長,但如果讀取的值超出范圍,如果第一個字符不是點,則它不會受到未定義的行為的影響,等等。沒有指定數字是否為負數,所以我使用了有符號類型但只允許正值,您可以通過允許內部while循環頂部的負號來輕松更改此值。 此版本允許任何非數字字符分隔整數,如果您只想要允許點,您可以修改內循環以僅跳過點,然后檢查數字。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#define ARRAY_SIZE 10
size_t store_numbers (const char *s, long *array, size_t elems)
{
/* Scan string s, returning the number of integers found, delimited by
* non-digit characters. If array is not null, store the first elems
* numbers into the provided array */
long value;
char *endptr;
size_t index = 0;
while (*s)
{
/* Skip any non-digits, add '-' to support negative numbers */
while (!isdigit(*s) && *s != '\0')
s++;
/* Try to read a number with strtol, set errno to 0 first as
* we need it to detect a range error. */
errno = 0;
value = strtol(s, &endptr, 10);
if (s == endptr) break; /* Conversion failed, end of input */
if (errno != 0) { /* Error handling for out of range values here */ }
/* Store value if array is not null and index is within array bounds */
if (array && index < elems) array[index] = value;
index++;
/* Update s to point to the first character not processed by strtol */
s = endptr;
}
/* Return the number of numbers found which may be more than were stored */
return index;
}
void print_numbers (const long *a, size_t elems)
{
size_t idx;
for (idx = 0; idx < elems; idx++) printf("%ld\n", a[idx]);
return;
}
int main (void)
{
size_t found, stored;
long numbers[ARRAY_SIZE];
found = store_numbers("..1....10..20....30...40....50...80...", numbers, ARRAY_SIZE);
if (found > ARRAY_SIZE)
stored = ARRAY_SIZE;
else
stored = found;
printf("Found %zu numbers, stored %zu numbers:\n", found, stored);
print_numbers(numbers, stored);
return 0;
}
我更喜歡在for循環中使用strtok。 雖然語法看起來有點奇怪,但讓它感覺更自然。
char str[] = "..1....10..20....30...40....50...80..."
for ( char* p = strtok( strtok, "." ); p != NULL; p = strtok( NULL, "." ) )
{
printf( "%d\n", atoi( p ) );
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.