Sscanf - 使用不同的分隔符进行解析
Sscanf - parsing with different delimiters
我想使用 sscanf 解析我的字符串:
char string[] = "/home/my/estf 122,323 452,323 662,343";
字符串的第一个元素是路径,接下来是整数,其中逗号或白色字符是分隔符。这是我的完整代码:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char string[] = "/home/my/estf 122,323 452,323 662,343";
char path[100];
int int1, int2, int3, int4, int5, int6;
sscanf(string, "%s %d[^,] %d %d[^,] %d %d[^,] %d",
path, &int1, &int2, &int3, &int4, &int5, &int6);
printf("Path:%s INT1:%d INT2:%d INT3:%d INT4:%d INT5:%d INT6:%d\n",
path, int1, int2, int3, int4, int5, int6);
return 0;
}
怎么了?是否可以扩展它,解析动态整数(不完全是 6)并将其存储在整数数组中?
你可以这样做:
char a[3][16], z;
int b[8] = {0};
char x[] = "/home/my/estf 122,323 452,323 662,343", y[64];
sscanf(x, "%c %[^/ ,] %c %[^/] %c %[^/ ] %d %c %d %d %c %d %d %c %d", &z, a[0], &z, a[1], &z, a[2], &b[0], &z, &b[1], &b[2], &z, &b[3], &b[4], &z, &b[5]);
for (int i = 0; i < 3; i++) {
printf("%s ", a[i]);
}
for (int i = 0; b[i] != 0; i++) {
printf("%d ", b[i]);
}
可能有更好的方法来做到这一点,但是使用 sscanf 你已经这样做了。您甚至可以将非常长的 sscanf
行转换为循环。
使用 sscanf 时,您必须使用您在否定扫描集中指定的字符。因此,如果是这样的扫描集:[^/] 将读取所有字符,直到第一次出现 /
。但是,指针仍将位于源字符串中的 /
处。您必须消费 /
并继续阅读。
有关 sscanf 如何工作的更多信息,请查看 man sscanf
Is it possible to extend it, to parse dynamic numbers of ints (no 6
exactly) and store it in integer array?
您可以在循环中使用 strtol
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char str[] = "/home/my/estf 122,323 452,323 662,343";
char path[100];
int ai[32];
char *ptr;
int n = 0;
ptr = strchr(str, ' ');
sprintf(path, "%.*s", ptr - str, str);
while (*ptr) {
ai[n++] = (int)strtol(ptr, &ptr, 10);
if (*ptr) ptr++;
}
printf("Path:%s", path);
for (int i = 0; i < n; i++) {
printf(" INT%d=%d", i + 1, ai[i]);
}
printf("\n");
return 0;
}
您似乎想使用类似 strtok()
的东西
这是example稍微修改一下:
/* strtok example */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ()
{
char string[] = "/home/my/estf 122,323 452,323 662,343";
char * pch;
pch = strtok (string, " ,");
while (pch != NULL)
{
pch = strtok (NULL, " ,");
if (pch)
{
int val = atoi(pch);
printf ("%d\n", val);
}
}
return 0;
}
我想使用 sscanf 解析我的字符串:
char string[] = "/home/my/estf 122,323 452,323 662,343";
字符串的第一个元素是路径,接下来是整数,其中逗号或白色字符是分隔符。这是我的完整代码:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char string[] = "/home/my/estf 122,323 452,323 662,343";
char path[100];
int int1, int2, int3, int4, int5, int6;
sscanf(string, "%s %d[^,] %d %d[^,] %d %d[^,] %d",
path, &int1, &int2, &int3, &int4, &int5, &int6);
printf("Path:%s INT1:%d INT2:%d INT3:%d INT4:%d INT5:%d INT6:%d\n",
path, int1, int2, int3, int4, int5, int6);
return 0;
}
怎么了?是否可以扩展它,解析动态整数(不完全是 6)并将其存储在整数数组中?
你可以这样做:
char a[3][16], z;
int b[8] = {0};
char x[] = "/home/my/estf 122,323 452,323 662,343", y[64];
sscanf(x, "%c %[^/ ,] %c %[^/] %c %[^/ ] %d %c %d %d %c %d %d %c %d", &z, a[0], &z, a[1], &z, a[2], &b[0], &z, &b[1], &b[2], &z, &b[3], &b[4], &z, &b[5]);
for (int i = 0; i < 3; i++) {
printf("%s ", a[i]);
}
for (int i = 0; b[i] != 0; i++) {
printf("%d ", b[i]);
}
可能有更好的方法来做到这一点,但是使用 sscanf 你已经这样做了。您甚至可以将非常长的 sscanf
行转换为循环。
使用 sscanf 时,您必须使用您在否定扫描集中指定的字符。因此,如果是这样的扫描集:[^/] 将读取所有字符,直到第一次出现 /
。但是,指针仍将位于源字符串中的 /
处。您必须消费 /
并继续阅读。
有关 sscanf 如何工作的更多信息,请查看 man sscanf
Is it possible to extend it, to parse dynamic numbers of ints (no 6 exactly) and store it in integer array?
您可以在循环中使用 strtol
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char str[] = "/home/my/estf 122,323 452,323 662,343";
char path[100];
int ai[32];
char *ptr;
int n = 0;
ptr = strchr(str, ' ');
sprintf(path, "%.*s", ptr - str, str);
while (*ptr) {
ai[n++] = (int)strtol(ptr, &ptr, 10);
if (*ptr) ptr++;
}
printf("Path:%s", path);
for (int i = 0; i < n; i++) {
printf(" INT%d=%d", i + 1, ai[i]);
}
printf("\n");
return 0;
}
您似乎想使用类似 strtok()
这是example稍微修改一下:
/* strtok example */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ()
{
char string[] = "/home/my/estf 122,323 452,323 662,343";
char * pch;
pch = strtok (string, " ,");
while (pch != NULL)
{
pch = strtok (NULL, " ,");
if (pch)
{
int val = atoi(pch);
printf ("%d\n", val);
}
}
return 0;
}