Вы извлекаете каждое целое число после символа «префикс», сначала находя символ префикса с помощью strchr
, а затем вызывая strtol
, начиная со следующего символа после префикса.
С вашей строкой, некоторым префиксным символом, взятым из командной строки (или использующим 'L'
по умолчанию, если не указан аргумент) и указателем на начало вашей строки:
int main (int argc, char **argv) {
char movimiento[]="L30 G10 L50 G-45 L-10 G50", /* string */
prefix = argc > 1 ? *argv[1] : 'L', /* prefix (L default) */
*p = movimiento; /* pointer to string */
Затем вы можете найтикаждое вхождение префикса в вашей строке с:
while ((p = strchr (p, prefix))) { /* while next prefix found */
...
Тогда нужно просто попытаться преобразовать в long, начиная со следующего символа:
errno = 0; /* set errno zero */
char *endptr; /* end-pointer for strtol */
long tmp = strtol (p + 1, &endptr, 0); /* convert from next char */
и проверить возвращаемое значениес strtol
вместе с endptr
, чтобы проверить наличие ошибки в результате попытки преобразования:
if (p == endptr) /* no digits convertedd */
p++; /* advance to next and try again */
Если цифры были преобразованы и errno
остается неустановленным, а значение long
возвращаетсяstrtol
находится в диапазоне int
, тогда у вас есть хорошее целочисленное значение, используйте его любым удобным вам способом:
else {
/* if no error and in range of int -- good value */
if (!errno && INT_MIN <= tmp && tmp <= INT_MAX) {
int val = (int)tmp;
printf (n ? ", %d" : "%d", val); /* output int */
n++; /* increment counter */
}
p = endptr; /* advance to one-past last digit converted */
}
( примечание: , пока естьПрежде чем преобразовать цифры, p
обновляется с помощью endptr
, чтобы указывать на следующий символ после последней преобразованной цифры, см. man 3 strtol )
Вы в основном сделали.Вы можете проверить, был ли выведен хотя бы один номер, и привести в порядок, выведя новую строку в этом случае с помощью:
if (n) putchar ('\n'); /* if integers found tidy up with newline */
}
Если положить его в целом, вы получите:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
int main (int argc, char **argv) {
char movimiento[]="L30 G10 L50 G-45 L-10 G50", /* string */
prefix = argc > 1 ? *argv[1] : 'L', /* prefix (L default) */
*p = movimiento; /* pointer to string */
int n = 0; /* counter */
while ((p = strchr (p, prefix))) { /* while next prefix found */
errno = 0; /* set errno zero */
char *endptr; /* end-pointer for strtol */
long tmp = strtol (p + 1, &endptr, 0); /* convert from next char */
if (p == endptr) /* no digits convertedd */
p++; /* advance to next and try again */
else {
/* if no error and in range of int -- good value */
if (!errno && INT_MIN <= tmp && tmp <= INT_MAX) {
int val = (int)tmp;
printf (n ? ", %d" : "%d", val); /* output int */
n++; /* increment counter */
}
p = endptr; /* advance to one-past last digit converted */
}
}
if (n) putchar ('\n'); /* if integers found tidy up with newline */
}
Пример Использование / Вывод
$ ./bin/intafterprefix
30, 50, -10
или с использованием префикса 'G'
:
$ ./bin/intafterprefix G
10, -45, 50
Просмотрите все и дайте мне знать, если у вас есть какие-либо дополнительные вопросы.
Обрабатывайте несколько префиксов с помощью strpbrk
Также отметьте, хотите ли вы иметь возможность передавать строку префиксов, позволяющую использовать "G"
или "L"
или "GL"
в качестве префиксных символов, вы можете сделать prefix
строкой и использовать strpbrk
вместо strchr
.Например, используя:
char movimiento[]="L30 G10 L50 G-45 L-10 G50", /* string */
*prefix = argc > 1 ? argv[1] : "L", /* prefix (L default) */
...
while ((p = strpbrk (p, prefix))) { /* while next prefix found */
...
Пример использования / Вывод
Это позволит вам искать любой или все префиксы, например,
$ ./bin/intafterprefix2
30, 50, -10
$ ./bin/intafterprefix2 G
10, -45, 50
$ ./bin/intafterprefix2 GL
30, 10, 50, -45, -10, 50