使用lseek并写入导致输入行被追加

时间:2018-01-22 00:32:15

标签: c file-handling

我试图逐行写入文件,但我无法做到。它被附加在同一行。请帮忙。

以下是示例代码:

int main()
 {
     long filesize;
     char sentence[1000];
     int count = 5;
     int m_iSourceFileData;
     int i = 0;
     long offset =0;

    if ((m_iSourceFileData = open("test.txt", O_RDWR | O_APPEND | O_CREAT,S_IWRITE | S_IREAD)) != -1)
     {
         while(i != count)
         {
             if ((lseek(m_iSourceFileData, offset, SEEK_SET)) != -1)
             {
                 printf("Enter a sentence: %d\n", i);
                 gets(sentence);
                 filesize = strlen(sentence);
                 write(m_iSourceFileData, sentence, filesize);
                 offset += filesize;
                 printf("Offset is %ld, filesize:%ld\n",offset,filesize);
                 i++;
             }

         }

         if(m_iSourceFileData != -1)
         {
             close(m_iSourceFileData);
             m_iSourceFileData = -1;
         }
     }
}

输入

$ a.out
Enter a sentence: 0
write
Offset is 5, filesize:5
Enter a sentence: 1
into
Offset is 9, filesize:4
Enter a sentence: 2
file
Offset is 13, filesize:4
Enter a sentence: 3
line after
Offset is 23, filesize:10
Enter a sentence: 4
line
Offset is 27, filesize:4

输出

writeintofileline afterline

2 个答案:

答案 0 :(得分:0)

不要使用gets,这是一个没有检查边界的危险功能, 它也从C11标准中删除。请改用fgets

gets返回包含一行的字符串,但不保存换行符 字符'\n'

write(m_iSourceFileData, sentence, filesize);

如果sentence没有换行符,您为什么希望找到换行符? 输出文件? write忘记了你的意图,它不会追加换行符 因为你想要它。

您有两种选择:

首先(不推荐):在字符串中附加换行符:

strcat(sentence, "\n");
filesize = strlen(sentence);
write(m_iSourceFileData, sentence, filesize);

第二个(推荐):永远不要使用gets,而是使用fgetsfgets会保存换行符(如果有的话) 缓冲区中有足够的空间)。请参阅fgets

printf("Enter a sentence: %d\n", i);
fgets(sentence, sizeof sentence, stdin);
filesize = strlen(sentence);
write(m_iSourceFileData, sentence, filesize);

您应该始终检查与之交互的函数的返回值 外面的世界,如fgets。您应该始终检查fgets是否有效 返回NULL

答案 1 :(得分:0)

open("test.txt", O_RDWR | O_APPEND | O_CREAT,S_IWRITE | S_IREAD)

以附加模式打开文件,flags包含O_APPEND

the POSIX open() documentation

  

...

     

可以使用以下任意组合:

     

O_APPEND

     

如果设置,则文件偏移量应设置为每次写入之前文件的末尾。

     

...

如果要写入以附加模式打开的文件中的特定偏移量,则can use pwrite()

  

pwrite()函数应相当于write(),除此之外   它写入给定位置并且不会更改文件偏移量   (无论是否设置O_APPEND)。前三个论点   pwrite()write()相同,但增加了第四个offset   参数pwrite()表示文件中的所需位置。一次尝试   对无法寻求的文件执行O_APPEND   导致错误。

但是,如果您正在运行Linux,pwrite() is broken

  

<强> BUGS

     

POSIX要求打开带有pwrite()标志的文件   对O_APPEND写入数据的位置没有影响。   但是,在Linux上,如果使用pwrite()打开文件,offset   将数据附加到文件的末尾,而不管其值是多少    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/wrapper" android:layout_width="300dp" android:weightSum="1" android:orientation="vertical" android:layout_height="300dp"> <LinearLayout android:id="@+id/LinearLayout02" android:layout_width="match_parent" android:layout_weight="0.33" android:layout_height="0dp"> <Button android:id="@+id/Button04" android:text="Button" android:layout_width="0dp" android:layout_weight="1" android:layout_height="fill_parent"></Button> <Button android:id="@+id/Button05" android:text="Button" android:layout_width="0dp" android:layout_weight="1" android:layout_height="fill_parent"></Button> <Button android:id="@+id/Button06" android:text="Button" android:layout_width="0dp" android:layout_weight="1" android:layout_height="fill_parent"></Button> </LinearLayout> <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="match_parent" android:layout_weight="0.33" android:layout_height="0dp"> <Button android:id="@+id/Button01" android:text="Button" android:layout_width="0dp" android:layout_weight="1" android:layout_height="fill_parent"></Button> <Button android:id="@+id/Button02" android:text="Button" android:layout_width="0dp" android:layout_weight="1" android:layout_height="fill_parent"></Button> <Button android:id="@+id/Button03" android:text="Button" android:layout_width="0dp" android:layout_weight="1" android:layout_height="fill_parent"></Button> </LinearLayout> <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_weight="0.33" android:layout_height="0dp"> <Button android:id="@+id/button1" android:text="Button" android:layout_weight="1" android:layout_width="0dp" android:layout_height="fill_parent"></Button> <Button android:id="@+id/button2" android:text="Button" android:layout_weight="1" android:layout_width="0dp" android:layout_height="fill_parent"></Button> <Button android:id="@+id/button3" android:text="Button" android:layout_weight="1" android:layout_width="0dp" android:layout_height="fill_parent"></Button> </LinearLayout> </LinearLayout> </LinearLayout>