在 C 中存储包含整数和字符的文件内容

Store contents of a file with both integers and characters in C

我有一个文本文件 input.txt,其内容的格式为:

12 3 /
2 3 -
3 4 *
1 2 4 + - 5 * 7 /

我的最终目标是读取文件的每一行并对给定的 RPN 表达式求值。我编写了以下代码片段来从 stdin 读取文件的内容并将其存储在字符数组中:

char expression[1000][256];
int i = 0;
while (fgets(expression[i], 256, stdin)) 
{   
    expression[i][strcspn(expression[i],"\r\n")] = 0;
    i++;
}

现在,我有了数组中的所有行。我这里的问题是我想存储这些,这样就没有空格,每个数字(所有数字)或字符都在一个单独的索引中。

例如,这里 expression[0][0] 是 1,expression[0][1] 是 2。但是,我希望 expression[0][0] 是 12,expression[0][1] 是 3,等等。

到目前为止,您的示例运行良好!感谢您发布一个问题来解释您想要的内容,并尝试解决它。​​

您遇到的主要问题是当您需要 array of array of strings 时存储 array of array of chars(记住 stringchar *) .

我使用了 [strtok][1] 方法,该方法每次遇到其调用中列出的字符之一时都会拆分一个字符串(使用 NULL 字符)。然后我分配内存,并将字符串复制到数组中。

我编写了一些示例代码 (try it online) 就是这样做的。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    char* expression[1000][256];
    char buffer[256];
    int line = 0;

    while (fgets(buffer, 256, stdin)) {
        int word = 0;
        char* token = strtok(buffer, " \r\n");
        do {
            expression[line][word] = calloc(sizeof(char), strlen(token) + 1);
            strcpy(expression[line][word], token);
            word++;
        } while ((token = strtok(NULL, " \r\n")) != NULL);
        line++;;
    }
    printf("'%s', '%s', '%s'\n", expression[0][0], expression[0][1], expression[0][2]);
    return 0;
}

您可能不需要将整个文件存储在内存中,而是一次读取一行,评估并打印结果:

  • 为一行输入定义一个足够长的缓冲区
  • 定义一个 int 数组用作 RPN 堆栈
  • 循环读取每一行输入
  • 在嵌套循环中,使用strtok,解析标记:

    • 如果令牌是一个数字,将其值压入堆栈
    • 如果token是一个运算符,则在栈顶的2个元素之间执行此操作,弹出它们后将结果存储到堆栈中。
  • 行尾,打印栈顶的值

您想对堆栈上溢和下溢执行简单检查。

这是一个示例实现:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    char buffer[256];
    int stack[sizeof(buffer) / 2]; // no need for stack overflow check
    int i, sp, tos;

    while (fgets(buffer, sizeof buffer, stdin)) {
        char *p = buffer, *token, *q;
        sp = -1;
        stack[++sp] = 1;
        stack[++sp] = 1;
        while ((token = strtok(p, " \t\r\n")) != NULL) {
            p = NULL;
            tos = stack[sp];
            if (!strcmp(token, "+")) {
                stack[--sp] += tos;
            } else
            if (!strcmp(token, "-")) {
                stack[--sp] -= tos;
            } else
            if (!strcmp(token, "*")) {
                stack[--sp] *= tos;
            } else
            if (!strcmp(token, "/")) {
                if (tos == 0 || (tos == -1 && stack[sp - 1] == INT_MAX)) {
                    printf("division overflow\n");
                    break;
                }
                stack[--sp] /= tos;
            } else
            if (!strcmp(token, "%")) {
                if (tos == 0 || (tos == -1 && stack[sp - 1] == INT_MAX)) {
                    printf("division overflow\n");
                    break;
                }
                stack[--sp] %= tos;
            } else {
                tos = strtol(token, &q, 0);
                if (q == token || *q != '[=10=]') {
                    printf("invalid token: %s\n", token);
                    break;
                }
                stack[++sp] = tos;
            }
            if (sp < 2) {
                printf("stack underflow for %s\n", token);
                break;
            }
        }
        if (token == NULL) {
            for (i = 2; i <= sp; i++) {
                printf("%d%c", stack[i], i == sp ? '\n' : ' ');
            }
        }
    }
    return 0;
}

输入:

12 3 /
2 3 -
3 4 *
1 2 4 + - 5 * 7 /

输出:

4
-1
12
-3