C - 使用sscanf读取算术运算符

时间:2013-06-22 02:55:54

标签: c math

我正在读一个字符串,它有两个数字,它们之间有一个算术运算符,如下所示:

A1 + B1
A1 - B1
A1 * B1
A1 / B1

我可以读取A1和B1但不能读取算子。我正在读这个:

while (sscanf(matrix[i][c] + offset, "%c%d%*c%n",
       &col, &line, &readCharCount) == 2) {
  // do something
}

如何阅读操作员?

4 个答案:

答案 0 :(得分:4)

与数字转换说明符和%s不同,%c转换说明符不会跳过空格。因此,根据您的示例输入,%*c正在读取操作符之前的空白。你明智地使用:

while (sscanf(matrix[i][c] + offset, " %c%d %c %c%d", &col1, &row1, &op, &col2, &row2) == 5)
    ...data is OK...

由于您正在使用偏移并且正在捕获扫描结束的位置,因此您将使用:

while (sscanf(matrix[i][c] + offset, " %c%d %c %c%d%n",
              &col1, &row1, &op, &col2, &row2, &readCharCount) == 5)
    ...data is OK...

请注意,%n转换说明符不计算在内,因此测试仍为5,而不是6。

另请注意在格式字符串中小心放置空格。它们是必要且灵活的(可以处理A1+B2 OK,以及A1 + B2)。如果您要允许更大的电子表格,您可能更愿意指定:

while (sscanf(matrix[i][c] + offset, " %4[a-zA-Z]%d %c %4[a-zA-Z]%d%n",
              col1, &row1, &op, col2, &row2, &readCharCount) == 5)
    ...data is OK...

col1col2的类型从单个变为char col1[5]; char col2[5];(这也是&被删除的原因)。扫描集允许识别aAa1 + BbB2之类的输入。由于%d表示法,字母或字母与数字之间允许有空格(因此代码允许aaa 999 + bbb 888。避免这种情况很难;我认为您需要处理两个数据scansets:

while (sscanf(matrix[i][c] + offset, " %4[a-zA-Z]%5[0-9] %c %4[a-zA-Z]%5[0-9]%n",
              col1, row1, &op, col2, row2, &readCharCount) == 5)
    ...data is OK...

其中类型现在为char row1[6]; char row2[6];,并且&符号已再次丢弃。然后,您可以放心地将row1row2转换为数字。

另请参阅:Calc cell convertor in C,以便将列号转换为相应的字母代码。

答案 1 :(得分:1)

如果我理解了这个问题,你就会读到两个数字,它们之间只有一个字符。因此,您使用格式字符串int将每个数字读入%d,然后使用格式字符串{{1}将字符读入字符串(char[]数组) }:

%s

请注意,您必须传递int nFirst; int nSecond; char op[5]; // operator, null, and some extra space to avoid overflow. while (sscanf(matrix[i][c] + offset, "%d %s %d", &nFirst, op, &nSecond) == 3) 变量的地址,但int数组的名称已解析为地址。

char[]的返回值应为3,因为返回已转换的的数量,并且您希望它填充3个变量。

答案 2 :(得分:0)

当您提供“%* c”时,表示读取一个字符并忽略该字符。所以,你忽略了格式字符串中的符号。我认为它按设计工作。你可能需要这样做。

char col, sign;
int line, readCharCount;

sscanf (matris[i][c] + offset, "%c%d%c%n", &col, &line, &sign, &readCharCount);

/* Read count and return value will be 3 */

A1 +将会阅读此内容。

col = 'A';
line = 1;
sign = '+'
readCharCount = 3;

这是你在找什么?

您更改了原始帖子。让我为新要求添加一些内容!

char a1[5], b1[5], sign;
int readCharCount;

sscanf (matris[i][c] + offset, "%s %c %s%n", a1, &sign, b1, &readCharCount);

/* Read count and return value will be 3 */

“A1 + B1”将像这样阅读。

a1 = "A1";  // String
sign = '+'  // Character
b1 = "B1";  // String
readCharCount = 3;  // No of items read. Return value will also be 3.

新输入流是:A1 + B1 + C1 + D1 + E2-F3 * G1

以下是要读取的代码,假设流以'\ n'终止:

char c1, c2, c3;

c1 = '\0';
while (c1 != '\n')
{
     scanf("%c%c%c", &c1, &c2, &c3);
     if(c1 != '\n')
     {
          /* Process characters */
     }
}

答案 3 :(得分:0)

我相信Adam的帖子是正确的,但是如果+和它后面的操作数之间没有空格,它会遇到问题。

使用“%d%s%d”,字符串“1234 +5555” 将导致%s捕获+5555。

我制作了以下程序,无论是否存在空格,都能正确捕获操作数。但是,变量字符串可能包含带有空格的字符串。 请注意,[^ 0123456789]表示“匹配所有不是数字的字符”。

int main (int argc, char ** argv) {
    int a, b;
    char string[100];
    scanf ("%d%[^0123456789 ]%d", &a, string, &b);

    printf ("a = %d\n", a);
    printf ("str = %s\n", string);
    printf ("b = %d\n", b);
}

我希望这有帮助!