在 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
(记住 string
是 char *
) .
我使用了 [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
我有一个文本文件 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
(记住 string
是 char *
) .
我使用了 [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