Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用C语言存储包含整数和字符的文件内容_C_Arrays_String_Stdin_Rpn - Fatal编程技术网

用C语言存储包含整数和字符的文件内容

用C语言存储包含整数和字符的文件内容,c,arrays,string,stdin,rpn,C,Arrays,String,Stdin,Rpn,我有一个文本文件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

我有一个文本文件
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++;
}
现在,我有了数组中的所有行。我在这里的问题是,我想存储这些,这样就没有空格,每个数字(所有数字)或字符都在一个单独的索引中


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

到目前为止,您的示例做得很好!感谢您发布一个问题,解释您想要什么,并尝试解决它

您遇到的主要问题是,当您需要字符串数组时,您正在存储字符数组的
数组(请记住
字符串
字符*

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

我编写了一些示例代码,就是这样做的

#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 main(){
字符*表达式[1000][256];
字符缓冲区[256];
内线=0;
而(fgets(缓冲区,256,标准输入)){
int字=0;
char*token=strtok(缓冲区“\r\n”);
做{
表达式[line][word]=calloc(sizeof(char),strlen(token)+1);
strcpy(表达式[行][字],标记);
word++;
}而((token=strtok(NULL,“\r\n”)!=NULL);
行++;;
}
printf(“%s”、“s”、“s”\n)、表达式[0][0]、表达式[0][1]、表达式[0][2]);
返回0;
}

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

  • 定义一个足以容纳一行输入的缓冲区
  • 定义一个
    int
    数组用作RPN堆栈
  • 在循环中,读取每行输入
  • 在嵌套循环中,使用strtok
,解析令牌:

  • 如果令牌是一个数字,则将其值推送到堆栈上
  • 如果令牌是运算符,则在堆栈的前两个元素之间执行此操作,并在弹出它们后将结果存储到堆栈中
  • 在行尾,打印堆栈顶部的值

  • 您希望对堆栈溢出和下溢执行简单检查

    下面是一个示例实现:

    #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 != '\0') {
                        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;
    }
    
    输出:

    4
    -1
    12
    -3
    

    使用
    fscanf
    而不是
    fgets
    。这是理解所读表达式所需的解析的一部分。如果数字是
    1234
    ,并且它不适合
    char
    ?也不能在1(
    expression[0][0]
    )的空间中放置两个字符(
    '1'
    '2'
    )。。。不要使用
    fscanf
    而不是
    fgets
    。首选
    fgets()
    后接
    sscanf()
    。这适用于1000行,但当我使用5000+时,会出现分段错误。有什么方法可以防止这种情况发生吗?@fereydoon318:是的,有多种方法可以防止这种情况发生;一种是根本不存储每一行——只需在输入时处理每一行(例如,参见下面的chqrlie答案的相关方面);或者,您可以在阅读更多的输入行时动态分配内存——动态内存分配是C编程(以及其他语言)中的一个普遍需要,在线上有很多资源可以指导您;嗯
    4
    -1
    12
    -3