我正在通过运行以下代码获取垃圾值
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
int fd,k;
fd=open("hello.txt",O_WRONLY|O_CREAT|O_TRUNC);
char a[1000];
scanf(" %s",a);
k=write(fd,a,sizeof(a));
close(fd);
}
为什么当我运行这个程序并输入字符串作为输入时,在hello.txt文件中会得到垃圾值?
2条答案
按热度按时间rt4zxlrg1#
因为
sizeof()
返回a
的内存大小,即1000。a
在堆栈上创建,其内容未定义。在scanf()
之后,仅覆盖此堆栈垃圾的第一部分。您需要执行
write(fd, a, strlen(a))
,或者如果您还想编写C字符串分隔符\0
(添加到a
的末尾),则使用strlen(a) + 1
。请检查操作
open()
、scanf()
和write()
的返回值,以确保所有步骤都执行无误。有关其返回值,请参阅手册页。ki1q1bka2#
到目前为止,您创建了一个最多可容纳1000个字符的变量。
这里你读取了一些字符(跳过单词前的所有空格,然后是一个单词---你只读取
a
,直到你得到一个空格字符或一个新行---),这意味着你只初始化了数组的一部分)假设输入字符串
"Se esta quemando la serreria"
,scanf()
函数只将'S'
、'e'
和'\0'
这三个字节放在a
的前三个位置...现在,您向
fd
写入a
的完整大小,这是描述其sizeof
值的1000个字符位置。相反,如果您计算了在字符串
a
中输入的字符数(您可以使用strlen()
库函数来实现此目的),则只写入了'\0'
字符之前的两个字符。最后一点:虽然
sizeof
和strlen()
都是函数,但事实并非如此:sizeof
是一个运算符,用于计算要引入的表达式的类型大小或类型名称的大小(在本例中,您需要括号,但在前面的示例中不需要)因此您可以只编写sizeof a
(没有括号,记住它是一个运算符)它的返回值是由编译器在编译时生成的,因为C中的类型是静态的(类型在程序执行期间不能改变)strlen()
是一个库函数,它允许你通过搜索字符串中的'\0'
字节来找到一个可变的字符串长度。通常,生成字符串的函数会用这样的字符来结束它们,并且它们的长度在运行时是可变的。这个函数允许你确定从a
写入的字符数,而不是完整的字符集。就像您在示例代码中所做的那样。