我正在尝试写入文件,但它无法正常工作。我可以打开一个文件,但是当使用write函数在文件中写入时,tt正在stdout本身写入,并且我打开的文件的内容保持不变。
#include<stdio.h>
#include<sys/file.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<limits.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/uio.h>
main() {
char fn[30];
int fd,i=0;
int actualbytes,bytesstored;
char buffer[100];
printf("\nEnter the filename with path");
scanf("%s",fn);
if(fd=open(fn,O_WRONLY|O_CREAT,S_IWUSR|S_IWUSR)<0)
{
perror("open");
exit(0);
}
else
{
write(stdout,"\n\nEnter the contents for the file\n");
write(stdout,"press CTRl+D at the end of the file\n\n");
fflush(stdout);
while((buffer[i]=getc(stdin))!=EOF) i++;
buffer[i]='\0';
bytesstored=sizeof(buffer);
if(actualbytes=write(fd,buffer,bytesstored)<0)
{
perror("write");
exit(0);
}
else
{
write(stdout,"\n\nfile is opened successfully");
write(stdout,"\nThe contents are written"); fflush(stdout);
}
if(close(fd)<0)
{
perror("close");
exit(0);
}
else
printf("\nfile is closed");
}
}
答案 0 :(得分:3)
<
的优先级高于=
。
if((fd=open(fn,O_WRONLY|O_CREAT,S_IWUSR|S_IWUSR))<0)
答案 1 :(得分:2)
此代码存在很多问题。确保在编译器上启用警告,它应该抱怨很多事情:
write()
位于unistd.h
。你没有包括那个,所以你的程序不正确。
一旦你包含它,你会注意到(启用了警告),你至少错误地调用了5次:stdout不是文件描述符,它是FILE*
。
使用printf()
系列函数在控制台上打印内容。
第二个大问题是你的if
语句中有分配。
if (a = b < 0) { ... }
相当于:
if (a = (b < 0)) { ... }
所以它没有做你认为的那样。你需要使用括号:
if ((fd = open(...)) < 0) { ... }
注意:您始终将完整缓冲区写入文件。并非所有这些都已初始化。这听起来不像你追求的那样。请尝试仅编写您已阅读的数据(您已将其存储在i
中)。
答案 2 :(得分:2)
请注意,来自stdin(3)
:
#include <stdio.h>
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
stdin
,stdout
是标准的IO FILE *
流,适用于fprintf(3)
,fgets(3)
,等等。
read(2)
和write(2)
采用文件描述符(表示为int
s)。
保持C提供的标准IO流和Unix提供的文件描述符在你的脑海中是分开的至关重要的来理解Unix编程;对不起,这很复杂:)但是值得成为专家。
我建议您将所有write(stdout,...
更改为fprintf(stdout,...
。
啊,我看到Ignacio发现了核心问题:)很难让一个人过去。
另一个需要担心的问题是,scanf()
调用不会将输入长度限制为缓冲区大小。有人可能会溢出你的缓冲区并乱写他们选择的内存数据。当你学习时,这并不是什么大不了的事,但这种错误正是first Internet worm感染了一些新机器的原因,所以不值得再犯同样的错误。
我发现的最后一个问题是你如何写出你的缓冲区:
buffer[i]='\0';
bytesstored=sizeof(buffer);
if(actualbytes=write(fd,buffer,bytesstored)<0)
sizeof(buffer)
总是会返回100
,因为这是您在程序开始时为buffer
声明的内容。所以用这个代替:
buffer[i++]='\0';
if(actualbytes=write(fd,buffer,i)<0)
答案 3 :(得分:1)
正如其他人所说,您的代码存在很多问题。始终指示编译器显示警告。如果您正在使用GCC,则传递参数-Wall
以显示所有警告。现在,如果我使用您的代码,它会建议以下内容:
write.c:9: warning: return type defaults to ‘int’
write.c: In function ‘main’:
write.c:18: warning: suggest parentheses around assignment used as truth value
write.c:25: warning: implicit declaration of function ‘write’
write.c:34: warning: suggest parentheses around assignment used as truth value
write.c:45: warning: implicit declaration of function ‘close’
write.c:55: warning: control reaches end of non-void function
第一个意味着您的函数main()
默认为int
,但您应始终声明返回类型。在第18行和第34行,您需要在分配周围使用括号,然后再使用&lt; (正如伊格纳西奥上面所说)。在第25和45行,它找不到write()
和close()
的原型,因此您需要包含正确的头文件。最后一个意味着您需要有一个return
语句(因为它默认为int
类型)。
答案 4 :(得分:0)
只需包含,警告就会消失。