搞笑写SysCall错误:在.txt

时间:2016-10-31 09:53:11

标签: c file-io system-calls ubuntu-16.04

在我的虚拟框Ubuntu图像下,我正在玩C中的打开和写入系统调用,并得到了我曾经遇到过的最有趣的错误!

基本上,我从open获取文件描述符,并将来自write funnction的输入写入.txt文件。用户告诉open函数在哪里查找文件/在哪里创建文件。

  • 如果该文件尚未创建,则打开将为我创建
  • 如果已经存在,我会将输入附加到文件的末尾

    int main(int argc, char* argv[]{
    int fd; 
    int bytesWritten;
    
    //open and create file if it's not been created yet
    fd = open(argv[1], O_CREAT|O_WRONLY|O_APPEND , S_IRWXU);
    if(fd == -1){
        perror("Open error:\n");
        exit(EXIT_FAILURE);
    }
    
    bytesWritten = write(fd,"Hello mate!\n",20);
    if(bytesWritten == -1){
        perror("Write error:\n");
        exit(EXIT_FAILURE);
    }
    //fysnc
    return 0;}
    

如果我将输出打印到stdout(1)(将fd更改为1),我将得到预期的结果:

  

你好伙伴!

但是,如果我使用如上所示的写,事情会变得非常奇怪(而且很有趣) Error

它让我大笑,文件被创建,如果我执行该程序几次,文件将开始增长和发展。

BTW,我执行这样的程序:

  

./ copy /home/b/Desktop/Examples/U3/test.txt

我必须承认这是一个非常有趣的副作用,但为什么会发生这种情况,我该如何解决?

好奇的

2 个答案:

答案 0 :(得分:1)

下面

write(fd,"Hello mate!\n",20);

写的比提供的更多。

字符串文字的大小为12 + 1 char s。代码写入20.所以七来自包含垃圾的无效内存。

这样做会调用未定义的行为,从那一刻开始就会发生任何事情。

要解决这个问题,你可以这样做:

write(fd, "Hello mate!\n", 12);

write(fd, "Hello mate!\n", sizeof "Hello mate!\n" - 1);

#define MYMSG "Hello mate!\n"

...

write(fd, MYMSG, sizeof MYMSG - 1);

char mymsg[] = "Hello mate!\n";

...

write(fd, mymsg, sizeof mymsg - 1);

char mymsg[] = "Hello mate!\n";

...

write(fd, mymsg, strlen(mymsg));

const char * pmymsg = "Hello mate!\n";

...

write(fd, pmymsg, strlen(pmymsg));

...

答案 1 :(得分:1)

好吧,伙计们,我刚刚找到了解决方案,我不得不为浪费你的时间而道歉......

我的合作伙伴重命名了文件所在的文件夹(例如,从Ü3到U3),然后点击回车。这种破坏了文件编码......

在另一个新文件夹中创建源文件可以解决问题..