如何使用fgets()来避免转换第二个int类型的参数?

Mic*_*chi 8 c casting

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 the `int` type */
Run Code Online (Sandbox Code Playgroud)

我已经声明了这种类型的长度size_t,但是如果我将它传递给fgets不好,因为:

conversion to ‘int’ from ‘size_t {aka long unsigned int}’ may alter its value
Run Code Online (Sandbox Code Playgroud)

如果我把它投射到int不适合因为它的大小int小于大小,length一些信息将丢失.

也许我在这里遗漏了一些东西......

我怎么能避免这种情况?

chu*_*ica 5

#include <stdio.h>
char *fgets(char * restrict s, int n, FILE * restrict stream);
Run Code Online (Sandbox Code Playgroud)

使用时fgets(),s[INT_MAX]无法使用输入缓冲区和更高版本.


OP的size_t len代码可能避免int的投len通过转换为字符串,并转换回一个int,那就是浪费.演员表演是正确的.

而不是乱丢代码(int),减少/控制其使用并将强制转换包装在限制辅助函数中.

int fgets_len(size_t len) {
  return (len < INT_MAX) ? (int) len : INT_MAX;
}


size_t len = something_big;
char *arr = malloc(len);

...   
if ( fgets(arr, fgets_len(len), stdin) == NULL){
    printf("Error, Fgets\n");
    exit(1);
}else{
    printf("Arr = '%s'\n", arr);
}
Run Code Online (Sandbox Code Playgroud)

如果代码确实需要读取行,请考虑此处ssize_t getline(char **lineptr, size_t *n, FILE *stream);定义的.请注意,这是一个非标准的C库函数,但其​​源代码随时可用.


关于迂腐使用fgets(),至少有两个原因fgets()要归还NULL:文件结束和输入错误.现在考虑使用OP代码的角落情况

size_t len = strlen("") + 1;
char arr[len];
if ( fgets(arr, (int)len, stdin) == NULL){
Run Code Online (Sandbox Code Playgroud)

和病理情况一样

if ( fgets(arr, 0, stdin) == NULL){
if ( fgets(arr, -1, stdin) == NULL){
Run Code Online (Sandbox Code Playgroud)

fgets()中讨论两者都返回NULL并且符合短缓冲器吗?