C write()函数不起作用
我正在尝试写入文件,但它无法正常工作。 我可以打开一个文件,但是当使用write函数在文件中写入时,tt正在stdout本身写入,并且我打开的文件的内容保持不变。
#include #include #include #include #include #include #include #include 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"); } }
<
具有比=
更高的优先级。
if((fd=open(fn,O_WRONLY|O_CREAT,S_IWUSR|S_IWUSR))<0)
这段代码存在很多问题。 确保在编译器上启用警告,它应该抱怨很多事情:
write()
在unistd.h
。 你不是那个,所以你的程序不正确。 一旦你包含它,你会注意到(启用了警告),你至少错误地调用了5次:stdout不是文件描述符,它是一个FILE*
。
使用printf()
函数系列在控制台上打印东西。
第二个大问题是你的if
语句中有赋值。
if (a = b < 0) { ... }
相当于:
if (a = (b < 0)) { ... }
所以它没有做你想象的那样。 你需要使用括号:
if ((fd = open(...)) < 0) { ... }
注意:您始终将完整缓冲区写入文件。 并非所有这些都已初始化。 这听起来不像你追求的那样。 尝试只编写您已阅读的数据(您已将其存储在i
)。
请注意,从stdin(3)
:
#include extern FILE *stdin; extern FILE *stdout; extern FILE *stderr;
stdin
, stdout
是标准IO FILE *
流,用于fprintf(3)
, fgets(3)
等。
read(2)
和write(2)
take filedescriptors(表示为int
s)。
保持C提供的标准IO流和Unix提供的文件描述符在您的脑海中分离对于理解Unix编程至关重要 ; 对不起它很复杂:)但是值得成为专家。
我建议改变你所有的write(stdout,...
到fprintf(stdout,...
。
啊,我看到伊格纳西奥发现了核心问题:)很难让一个人过去。
另一个需要担心的问题是, scanf()
调用不会将输入的长度限制为缓冲区的大小。 有人可能会溢出你的缓冲区并乱写他们选择的内存数据。 当你正在学习时,这并不是什么大不了的事,但这种错误正是第一个互联网蠕虫感染了一些新机器的原因,所以不值得再犯同样的错误。
我发现的最后一个问题是你如何写出你的缓冲区:
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)
正如其他人所说,您的代码存在很多问题。 始终指示编译器显示警告。 如果您正在使用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行,在使用<进行测试之前,您需要在作业周围使用括号(如上面的Ignacio所述)。 在第25和45行,它找不到write()
和close()
的原型,因此您需要包含正确的头文件。 最后一个意味着你需要一个return
语句(因为它默认为int
类型)。
只是包括,警告将消失。