C write()函数不起作用

时间:2011-03-12 10:24:53

标签: c

我正在尝试写入文件,但它无法正常工作。我可以打开一个文件,但是当使用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"); 
 } 
}

5 个答案:

答案 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;

stdinstdout是标准的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)

只需包含,警告就会消失。