使用 fgets() 从 stdout 读取行
Reading lines from stdout with fgets()
阅读了文档、Stack 答案和 C 标准后,我似乎仍然没有得到一些东西。
我想将输出重定向到某个文件,然后将输出与预测结果进行比较;我将使用评论指出主要问题
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SEQ 120
void printer() {
for (int i = 0; i < 5; i++) {
printf("%d0 ", i);
for (int j = 0; j < 6; j++) {
printf("0%d ", j);
}
printf("\n");
}
printf("\n");
}
void check_string() {
FILE* pointer = freopen("./check_str_out", "w", stdout);
char* storage = malloc(MAX_SEQ);
char* test_results[] = {"00 00 01 02 03 04 05 \n", "10 00 01 02 03 04 05 \n",
"20 00 01 02 03 04 05 \n", "30 00 01 02 03 04 05 \n", "40 00 01 02 03 04 05 \n", "\n"};
int counter = 0;
printer();
freopen("/dev/tty", "w", stdout);
FILE* output = fopen("./check_str_out", "r"); //It was added in the new version
printf("sth\n");
while (fgets(storage, MAX_SEQ, output)) { //previous: while (fgets(storage, MAX_SEQ, pointer))
printf("sth2\n");
printf("count: %d, stor: %s, test: %s, comp: %d\n", counter, storage, test_results[counter], strcmp(storage, test_results[counter])); //E) strcmp(storage, test_results[counter++])
counter++;
}
free(storage);
fclose(output);
}
int main(void) {
check_string();
return 0;
}
问题是:为什么我使用pointer
时这段代码不起作用?为什么我必须打开文件?现在一切都正确了。我也测试过:
FILE* pointer = freopen("./check_str_out", "w+", stdout);
为了检查是否是模式的问题,但是没有成功。
为清楚起见:如果使用了 fgets() 中的指针,它不会打印 while 循环,它不会进入它。
编辑:
从 this description 我看不到 freopen()
打开的文件的 fclose()
,但看起来流已关闭。这是什么原因?
您正在越界访问 test_results
,因此您的程序具有 undefined behavior。
void printer() {
for (int i = 0; i < 5; i++) {
printf("%d0 ", i);
for (int j = 0; j < 6; j++) {
printf("0%d ", j);
}
printf("\n");
}
printf("\n"); // this line makes it print 6 lines to the file
}
并且在您的 while
循环中 counter
将到达 5
而 test_results[5]
超出范围。
始终从可能会失败的函数中测试 return 值,例如 freopen
,并确保您在依赖外部数据时没有 运行 越界 (就像您的数据文件一样,可能会因其他原因而损坏)。
示例:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SEQ 120
void printer() {
for (int i = 0; i < 5; i++) {
printf("%d0 ", i);
for (int j = 0; j < 6; j++) {
printf("0%d ", j);
}
printf("\n");
}
printf("\n"); // this extra line doesn't matter if you check bounds later
}
void check_string() {
if (freopen("./check_str_out", "w", stdout)==NULL) {
perror("./check_str_out");
return;
}
char* storage = malloc(MAX_SEQ);
if (storage == NULL) {
perror("malloc");
return;
}
char* test_results[] = {"00 00 01 02 03 04 05 \n",
"10 00 01 02 03 04 05 \n",
"20 00 01 02 03 04 05 \n",
"30 00 01 02 03 04 05 \n",
"40 00 01 02 03 04 05 \n"};
int counter = 0;
printer();
if (freopen("/dev/tty", "w", stdout) == NULL) {
perror("/dev/tty");
return;
}
FILE* output = fopen("./check_str_out", "r");
if(output == NULL) {
perror("./check_str_out");
return;
}
while (counter < sizeof test_results / sizeof *test_results &&
fgets(storage, MAX_SEQ, output))
{
printf("count: %d, stor: %s, test: %s, comp: %d\n", counter,
storage, test_results[counter],
strcmp(storage, test_results[counter]));
counter++;
}
free(storage);
fclose(output);
}
int main(void) {
check_string();
return 0;
}
关于pointer
:
pointer == stdout
贯穿整个节目 FILE* pointer = freopen("./check_str_out", "w", stdout);
之后。您无法 从 stdout
读取 。它是只写的。
"我看不到 freopen()
打开的文件的 fclose()
,但看起来流已关闭。这是什么原因? " - stdout
在程序终止时自动关闭。
阅读了文档、Stack 答案和 C 标准后,我似乎仍然没有得到一些东西。
我想将输出重定向到某个文件,然后将输出与预测结果进行比较;我将使用评论指出主要问题
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SEQ 120
void printer() {
for (int i = 0; i < 5; i++) {
printf("%d0 ", i);
for (int j = 0; j < 6; j++) {
printf("0%d ", j);
}
printf("\n");
}
printf("\n");
}
void check_string() {
FILE* pointer = freopen("./check_str_out", "w", stdout);
char* storage = malloc(MAX_SEQ);
char* test_results[] = {"00 00 01 02 03 04 05 \n", "10 00 01 02 03 04 05 \n",
"20 00 01 02 03 04 05 \n", "30 00 01 02 03 04 05 \n", "40 00 01 02 03 04 05 \n", "\n"};
int counter = 0;
printer();
freopen("/dev/tty", "w", stdout);
FILE* output = fopen("./check_str_out", "r"); //It was added in the new version
printf("sth\n");
while (fgets(storage, MAX_SEQ, output)) { //previous: while (fgets(storage, MAX_SEQ, pointer))
printf("sth2\n");
printf("count: %d, stor: %s, test: %s, comp: %d\n", counter, storage, test_results[counter], strcmp(storage, test_results[counter])); //E) strcmp(storage, test_results[counter++])
counter++;
}
free(storage);
fclose(output);
}
int main(void) {
check_string();
return 0;
}
问题是:为什么我使用pointer
时这段代码不起作用?为什么我必须打开文件?现在一切都正确了。我也测试过:
FILE* pointer = freopen("./check_str_out", "w+", stdout);
为了检查是否是模式的问题,但是没有成功。
为清楚起见:如果使用了 fgets() 中的指针,它不会打印 while 循环,它不会进入它。
编辑:
从 this description 我看不到 freopen()
打开的文件的 fclose()
,但看起来流已关闭。这是什么原因?
您正在越界访问 test_results
,因此您的程序具有 undefined behavior。
void printer() {
for (int i = 0; i < 5; i++) {
printf("%d0 ", i);
for (int j = 0; j < 6; j++) {
printf("0%d ", j);
}
printf("\n");
}
printf("\n"); // this line makes it print 6 lines to the file
}
并且在您的 while
循环中 counter
将到达 5
而 test_results[5]
超出范围。
始终从可能会失败的函数中测试 return 值,例如 freopen
,并确保您在依赖外部数据时没有 运行 越界 (就像您的数据文件一样,可能会因其他原因而损坏)。
示例:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SEQ 120
void printer() {
for (int i = 0; i < 5; i++) {
printf("%d0 ", i);
for (int j = 0; j < 6; j++) {
printf("0%d ", j);
}
printf("\n");
}
printf("\n"); // this extra line doesn't matter if you check bounds later
}
void check_string() {
if (freopen("./check_str_out", "w", stdout)==NULL) {
perror("./check_str_out");
return;
}
char* storage = malloc(MAX_SEQ);
if (storage == NULL) {
perror("malloc");
return;
}
char* test_results[] = {"00 00 01 02 03 04 05 \n",
"10 00 01 02 03 04 05 \n",
"20 00 01 02 03 04 05 \n",
"30 00 01 02 03 04 05 \n",
"40 00 01 02 03 04 05 \n"};
int counter = 0;
printer();
if (freopen("/dev/tty", "w", stdout) == NULL) {
perror("/dev/tty");
return;
}
FILE* output = fopen("./check_str_out", "r");
if(output == NULL) {
perror("./check_str_out");
return;
}
while (counter < sizeof test_results / sizeof *test_results &&
fgets(storage, MAX_SEQ, output))
{
printf("count: %d, stor: %s, test: %s, comp: %d\n", counter,
storage, test_results[counter],
strcmp(storage, test_results[counter]));
counter++;
}
free(storage);
fclose(output);
}
int main(void) {
check_string();
return 0;
}
关于pointer
:
pointer == stdout
贯穿整个节目 FILE* pointer = freopen("./check_str_out", "w", stdout);
之后。您无法 从 stdout
读取 。它是只写的。
"我看不到 freopen()
打开的文件的 fclose()
,但看起来流已关闭。这是什么原因? " - stdout
在程序终止时自动关闭。