我最近刚开始工作I/O在C.这是我的问题 -
我有一个文件,我从中读取了我的输入.然后我用来fgets()在缓冲区中获取字符串,我以某种方式使用它.现在,如果输入对于缓冲区而言太短,即第一次读取fgets()到达时会发生什么EOF.应该fgets()返回NULL(正如我在fgets()文档中看到的那样)?它似乎没有,我得到了正确的输入.除了我feof(input)不说我们已达到EOF.
这是我的代码片段.
char buf[BUFSIZ];
FILE *input,
*output;
input = fopen(argv[--argc], "r");
output = fopen(argv[--argc], "w");
/**
* If either of the input or output were unable to be opened
* we exit
*/
if (input == NULL) {
fprintf(stdout, "Failed to open file - %s.\n", argv[argc + 1]);
exit(EXIT_FAILURE);
}
if (output == NULL) {
fprintf(stdout, "Failed to …Run Code Online (Sandbox Code Playgroud) fgets函数的声明如下所示:
char *fgets(char *str, int n, FILE *stream);
Run Code Online (Sandbox Code Playgroud)
这意味着第二个参数应该是一个int.
在以下程序中哪种方法可以避免这种转换?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
const char *buffer = "Michi";
size_t len = strlen(buffer) + 1;
char arr[len];
printf("Type your Input:> ");
if (fgets(arr, (int)len, stdin) == NULL) {
printf("Error, fgets\n");
exit(1);
} else {
printf("Arr = %s\n", arr);
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我使用(int)len哪个看起来很好,但如果buffer存储一个很长的字符串会发生什么?
让我们说:
const char *buffer = "Very long long ..."; /* where length is beyond the range of …Run Code Online (Sandbox Code Playgroud) 在查看fgets§7.21.7.2,3 的ISO C11标准时,会根据概要代码说明返回值:
#include <stdio.h>
char *fgets(char* restrict s, int n, FILE* restrict stream);
Run Code Online (Sandbox Code Playgroud)
如果成功,fgets函数返回s.如果遇到文件结尾且没有字符读入数组,则数组的内容保持不变,并返回空指针.如果在操作期间发生读取错误,则数组内容是不确定的,并返回空指针.
该标准表示为eof返回空指针,并且没有读入任何字符或发生读取错误.我的问题是,只是来自fgets和返回的空指针,是否有办法区分导致错误的两种情况中的哪一种?
我一直在努力处理系统调用的返回值 - 它们只是如此不一致!通常我检查它们是否为NULL或-1然后调用perror.但是,对于fgets,手册页说:
gets()并fgets()返回如果成功,就和NULL对错误或者虽然没有字符被读取时的文件结束.
这意味着返回值NULL不一定是错误 - 它也可以是EOF.到达文件末尾时是否设置了错误?perror在这种情况下我还能打电话吗?
如果不是,通常的方法是判断调用是否返回错误与EOF.我想使用perrorNULL字符串表示错误,并使用自定义字符串表示EOF.
我正在创建一个带有提示的命令行应用程序。只要输入适合缓冲区,它就可以正常工作,但是当输入较大时,我会出现一些奇怪的行为。下面是一个简化的最小示例,它具有相同的错误。
int main()
{
for (;;) {
const int size = 8;
char str[size];
printf("> ");
fgets(str, size, stdin);
toupper_str(str);
printf("Result: %s\n", str);
}
}
Run Code Online (Sandbox Code Playgroud)
如果输入小于size.
> asdf
Result: ASDF
>
Run Code Online (Sandbox Code Playgroud)
当输入较大时,处理范围内的输入部分,并在下一次循环迭代中,立即从 返回给定输入的其余部分fgets。这导致输入的那部分也被处理和一些奇怪的输出。
> asdfghjk
Result: ASDFGHJ
> Result: K
>
Run Code Online (Sandbox Code Playgroud)
我可以通过将最后一个字符与换行符进行比较来查看输入是否大于或等于 size。fgets只要它适合,就保留换行符。
fgets(str, size, stdin);
if (str[strlen(str) - 1] != '\n') {
fprintf(stderr, "Input too long\n");
}
Run Code Online (Sandbox Code Playgroud)
当检测到这种情况时,如何阻止它在下一次迭代中读取剩余的过长输入?
我在这里看到过类似的问题,但没有人提出同样的问题。