用户输入与字符数组和fgets?

问题描述

@H_502_0@由于某些原因,这段代码给了我一个损坏的最终字符-写入文件和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;
}

解决方法

write中遇到问题,您需要在count参数中传递字符串的长度,而不是20: ie strlen(user_input) / p>

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

否则,它将写入所有20个字符,而不管存储在user_input中的字符串的大小如何。 例如,如果字符串有8个字符,它将写入这8个字符,空终止符以及char数组其余元素中存储的所有垃圾值,直到大小为20。

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

请记住,当您从文件中读取字符串时,需要手动 对其进行空终止,上述write不会在文件中存储空字节。


关于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