如何使用 scanf 从缓冲区中提取一些格式化的字符串?
How to extract some formatted string from the buffer using scanf?
我需要从那个长字符串中提取 "rudolf" 和 "12":"hello, i know that rudolph=12 but it so small..."
使用 scanf
,我该怎么做?
此缓冲区可以包含任何格式的字符串,如 ruby=45
或 bomb=1
,我事先并不知道。
我正在尝试类似的方法,但没有成功
#include <stdio.h>
int main()
{
char sentence[] = "hello, i know that rudolph=12 but it so small...";
char name[32];
int value;
sscanf(sentence, "%[a-z]=%d", name, &value);
printf("%s -> %d\n", name, value);
getchar();
return 0;
}
使用临时指针遍历句子并%n
提取每个子字符串。
%n
将给出扫描到该点所处理的字符数。将其添加到临时指针以推进句子。
尝试从每个子字符串中解析名称和值。扫描集 %31[^=]
将扫描最多 31 个字符,在 name
中留出空间用于终止零。它将扫描所有不是 =
的字符。然后格式字符串将扫描 =
并尝试扫描一个整数。
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char sentence[] = "hello, i know that rudolph=12 but it so small...";
char string[sizeof sentence] = "";
char name[32] = "";
char *temp = sentence;
int value = 0;
int count = 0;
int parsed = 0;
while (1 == sscanf(temp, "%s%n", string, &count)) {
temp += count;
if (2 == sscanf(string, "%31[^=]=%d", name, &value)) {
parsed = 1;
break;
}
}
if (parsed) {
printf("%s %d\n", name, value);
}
return 0;
}
您可以编写自己的字符串搜索引擎。这可能很简单,让我们举个例子:
- 前进,直到找到
[a-z]
之一
- 记住位置
- 前进到
[a-z]
结束
- 检查现在是否
=
- 如果是,那就是我们的变量名
- 前进到值结束
- return它
- 如果没有
=
,请忽略所有不是 [a-z]
的内容,即。不能是变量名
示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
struct find_assignment_s {
const char *line;
const char *var;
size_t varlen;
const char *val;
size_t vallen;
};
struct find_assignment_s find_assignment_init(const char *line) {
return (struct find_assignment_s){.line = line};
}
int find_assignment(struct find_assignment_s *t) {
while (*t->line) {
const char *p = t->line;
while (*p && isalpha((unsigned char)*p)) p++;
// There is at least one alphabetic character and there is a space right after.
if (t->line != p && *p == '=') {
// Found a "variable="!
t->var = t->line;
t->varlen = p - t->line;
// value is up until a space is found
t->val = p + 1;
while (*p && !isspace((unsigned char)*p)) p++;
t->vallen = p - t->val;
// Advance the pointer behind value.
t->line = *p ? p + 1 : p;
return 1;
}
// Ignore spaces
while (*p && !isalpha((unsigned char)*p)) p++;
// Advance over whole word.
t->line = p;
}
return 0;
}
int main() {
const char line[] = "hello, i know that rudolph=12 but it so small... a=b c=d fdnajn=123";
for (struct find_assignment_s fs = find_assignment_init(line);
find_assignment(&fs) == 1; ) {
printf("%.*s = %.*s\n", (int)fs.varlen, fs.var, (int)fs.vallen, fs.val);
}
}
输出:
rudolph = 12
a = b
c = d
fdnajn = 123
我需要从那个长字符串中提取 "rudolf" 和 "12":"hello, i know that rudolph=12 but it so small..."
使用 scanf
,我该怎么做?
此缓冲区可以包含任何格式的字符串,如 ruby=45
或 bomb=1
,我事先并不知道。
我正在尝试类似的方法,但没有成功
#include <stdio.h>
int main()
{
char sentence[] = "hello, i know that rudolph=12 but it so small...";
char name[32];
int value;
sscanf(sentence, "%[a-z]=%d", name, &value);
printf("%s -> %d\n", name, value);
getchar();
return 0;
}
使用临时指针遍历句子并%n
提取每个子字符串。
%n
将给出扫描到该点所处理的字符数。将其添加到临时指针以推进句子。
尝试从每个子字符串中解析名称和值。扫描集 %31[^=]
将扫描最多 31 个字符,在 name
中留出空间用于终止零。它将扫描所有不是 =
的字符。然后格式字符串将扫描 =
并尝试扫描一个整数。
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char sentence[] = "hello, i know that rudolph=12 but it so small...";
char string[sizeof sentence] = "";
char name[32] = "";
char *temp = sentence;
int value = 0;
int count = 0;
int parsed = 0;
while (1 == sscanf(temp, "%s%n", string, &count)) {
temp += count;
if (2 == sscanf(string, "%31[^=]=%d", name, &value)) {
parsed = 1;
break;
}
}
if (parsed) {
printf("%s %d\n", name, value);
}
return 0;
}
您可以编写自己的字符串搜索引擎。这可能很简单,让我们举个例子:
- 前进,直到找到
[a-z]
之一- 记住位置
- 前进到
[a-z]
结束
- 检查现在是否
=
- 如果是,那就是我们的变量名
- 前进到值结束
- return它
- 如果没有
=
,请忽略所有不是[a-z]
的内容,即。不能是变量名
示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
struct find_assignment_s {
const char *line;
const char *var;
size_t varlen;
const char *val;
size_t vallen;
};
struct find_assignment_s find_assignment_init(const char *line) {
return (struct find_assignment_s){.line = line};
}
int find_assignment(struct find_assignment_s *t) {
while (*t->line) {
const char *p = t->line;
while (*p && isalpha((unsigned char)*p)) p++;
// There is at least one alphabetic character and there is a space right after.
if (t->line != p && *p == '=') {
// Found a "variable="!
t->var = t->line;
t->varlen = p - t->line;
// value is up until a space is found
t->val = p + 1;
while (*p && !isspace((unsigned char)*p)) p++;
t->vallen = p - t->val;
// Advance the pointer behind value.
t->line = *p ? p + 1 : p;
return 1;
}
// Ignore spaces
while (*p && !isalpha((unsigned char)*p)) p++;
// Advance over whole word.
t->line = p;
}
return 0;
}
int main() {
const char line[] = "hello, i know that rudolph=12 but it so small... a=b c=d fdnajn=123";
for (struct find_assignment_s fs = find_assignment_init(line);
find_assignment(&fs) == 1; ) {
printf("%.*s = %.*s\n", (int)fs.varlen, fs.var, (int)fs.vallen, fs.val);
}
}
输出:
rudolph = 12
a = b
c = d
fdnajn = 123