【问题标题】:user input with char array and fgets?使用 char 数组和 fgets 的用户输入?
【发布时间】:2021-01-26 06:57:30
【问题描述】:

由于某种原因,这段代码给了我一个损坏的最终字符——写入文件和 printf 都没有输入最后一个字符

#include <stdio.h>
#include <stdlib.h>
#include "ssem.h"

int main(){
    int sem_WF, sem_WF_key = 123456, fileID, callStatus;
    char user_input[21];
    
    /*sem_WF = sem_open(sem_WF_key);*/

    fileID = creat ("data", 384);
    if (fileID<0) {printf("Error with creat"); return 0;}

    printf("Enter up to 20 characters: ");
    
    fgets(user_input, 20, stdin);
    printf("%s\n", user_input);

    callStatus = write(fileID, user_input, 20);
    if (callStatus<0) {printf("error with write"); return 0;}

    callStatus = close(fileID);
    if (callStatus<0) {printf("error with close"); return 0;}

    return 0;
}

【问题讨论】:

  • fgets(user_input, 20, stdin); 将在user_input 中写入除'\0' 之外的最多19 个字符(总共最多20 个),顺便说一句,您正确定义为能够容纳21 个字符。我很懒...我通常这样做fgets(foo, sizeof foo, stdin)
  • @pmg,如果我可以插话,我认为你一点也不懒,写sizeof foo实际上比写20更费力;)
  • @anastaciu,好吧,在我有时使用100,或1000,或500,或20,或256,...(取决于我不知道是什么)而且检查我使用的内容比输入sizeof buf 更麻烦(通常这种数组也称为buf):)
  • @pmg,我明白了,这是最好的懒惰

标签: c file-io fgets write


【解决方案1】:

write你有问题,你需要在count参数中传递字符串的长度,strlen(user_input)而不是20:

write(fileID, user_input, strlen(user_input));

否则,无论user_input 中存储的字符串大小如何,它都会写入全部 20 个字符。 例如如果字符串有 8 个字符,它将写入这 8 个字符加上空终止符以及存储在 char 数组的其余元素中的任何垃圾值,直到大小为 20。

还要注意,由于您使用fgets 的方式,字符串的实际长度永远不会是20,它最多有19个字符+空字节(前面有更多细节),这个空字节也是写入文件。

请记住,当您从文件中读取字符串时,您需要手动将其终止,上面的write 不会将空字节存储在文件中。 p>


关于fgets,它将在目标缓冲区的最后一个字符中存储空字节\0,因此如果您传递20的大小,它将最多存储19个字符+空字节。好的做法是使用目标缓冲区的大小:

fgets(user_input, sizeof user_input, stdin);

还要注意的是fgets 存储了输入流中存在的\n 换行符。

使用fgets 解析的字符串将如下所示:

+---+---+---+---+---+---+----+----+
|'s'|'t'|'r'|'i'|'n'|'g'|'\n'|'\0'|
+---+---+---+---+---+---+----+----+

除非\n 被存储在目标缓冲区的最后一个元素中,在这种情况下,它将被留在stdin 缓冲区中,取而代之的是\0

如果您愿意,可以删除此 \n 字符:

user_input[strcspn(user_input, "\n")] = '\0'; //#include <string.h>

这是一个 Live Demo 已修复问题。

【讨论】:

    猜你喜欢
    • 2021-03-25
    • 2012-10-05
    • 1970-01-01
    • 2016-05-06
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多