我正在编写一个可以加密文本文件的程序。
首先,我需要向用户询问文件名。我做了类似的事情:
char file_name[50];
fgets(file_name, 50, stdin);
但它没有用。我怎样才能做到这一点?
我很困惑,如果我将文件名存储在一个 char 数组中,该数组有 50 个元素,但文件名只有 10 个字符。当我将数组或指针传递给 时fopen
,程序将如何处理该数组的剩余 40 个元素?他们是否存储任何价值?他们会被传递给fopen
?
在 C 中,字符串只是一个\0
终止的字符序列。只要\0
在 的 50 个字节内有一个file_name
,就file_name
包含 的有效字符串fopen()
。
可能失败的原因fopen()
是您传递给它的名称\n
在从输入中读取后有一个额外的名称。这是因为fgets()
还将换行符存储到缓冲区中。在将字符串用作文件名之前,您必须将其删除。
char *p = strrchr(file_name, '\n');
if (p) *p = '\0';
我很困惑,如果我将文件名存储在一个 char 数组中,比如说,它有 50 个元素。但文件名只有 10 个字符。当我将数组或指针传递给 fopen() 函数时,程序将如何处理该数组的其余 40 个元素?
你是说剩下的38个,对吧?第 11 个字符将是fgets()
放入缓冲区的换行符,第 12 个字符被分配一个 NUL ( '\0'
) 字符。
它不会对其余部分做任何事情。
他们是否存储任何价值?它们会被传递给 fopen() 吗?
显然,它们存储了一些价值,无论如何这都是不确定和无关的。不,它们不会被传递给fopen()
. 事实上,没有一个字符会被传递给fopen()
. 当您将数组用作函数的参数时,它会自动衰减为指向其第一个元素的指针,并且只有该指针可以fopen()
看到。
在内部,fopen()
最有可能使用open()
系统调用实现(至少在 Unices 上),并且几乎每个函数都接受 C 字符串,它将通过搜索 NUL 终止符并假设文件名由最多(但不包括)该字符的'\0'
字符。
fopen
将逐字符检查字符串,直到遇到\0
,然后停止。因此,您从中获得的字符串的其余部分fgets
无关紧要,只要前 10 个字符加上尾随\0
构成有效字符串即可。
另请注意,您需要\n
从获得的字符串中删除多余的fgets
.
C 中的字符串只是内存中的字符,后跟一个空字节。例如:
'H' 'e' 'l' 'l' 'o' ',' ' ' 'w' 'o' 'r' 'l' 'd' '!' '\0'
48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 00
当您将数组传递给 的文件名参数时fopen
,它会衰减为指针。本质上,fopen
它将使用最多并不包括空字节的字符。之后的任何东西都没有被触及。