C 使用系统调用将 .text 转换为二进制文件

C converts .txt to binary file using System Calls

我正在编写一个程序来替换 position % step = 0 中的每个字符 作为命令行参数,我给出 1. file 2. character3. step。我只能使用系统调用。这是我的主要功能:

int main(int argc, char **argv){

   assert(argc ==  4);

   int fdInput = open(argv[1], O_WRONLY);
   if(fdInput == -1)
      fatalError("Error opening input file.\n");

   char c[1];
   c[0] = argv[2][0];
   unsigned step = atoi(argv[3]);

   int fileSize;
   if((fileSize = lseek(fdInput,0,SEEK_END)) < 0)
      fatalError("Lseek error: Determining file size\n");

   if(lseek(fdInput,0,SEEK_SET) == -1)
      fatalError("Lseek error: Returning to the beginning\n");

   int i;
   for(i = 0; i*step < fileSize; i++)

      if(step - 1 > 0){
         if(lseek(fdInput, i*step - 1, SEEK_SET) == -1)
            fatalError("Lseek error: Within loop\n");

         if(write(fdInput, c, 1) != 1)
            fatalError("Writing error\n");

      }
      else {

         if(write(fdInput, c, 1) != 1)
            fatalError("Writing error.\n");
      }
      close(fdInput);
      return 0;
   }

示例:

input.txt: 123456789

./output input.txt x 3 会 return 12x45x78x

问题: 由于某些原因,当我第一次编译和执行时,一切正常!但是:当我第二次执行它时,它不起作用。当我尝试 cat/less input.txt 它告诉我文件是二进制的。

文件怎么可能是二进制的?它应该是纯文本文件。我在这里做错了什么? open 我是不是做错了什么?

你的第一个查找偏移量是错误的:

i*step - 1

with i == 0 这会产生 -1,仅考虑纯数学计算并将隐式类型转换排除在游戏之外。然后将其转换为 unsignedoff_t 已签名,传递的负值应导致 EINVAL,因此它必须是隐式转换)这将非常大( UINT_MAX)。结果是一个非常大(但稀疏)的文件。

哦,还有:

assert(argc ==  4);

assert 用于检查不变量,而不是用于处理不正确的用户输入。

您应该将 i 初始化为 1 而不是 0 即

for(i = 1; i*step < fileSize; i++)

否则,正如@Daniel Jour 所说,您的第一个搜索偏移量将是错误的(i*step - 1 == -1,仅考虑纯数学计算并将隐式类型转换排除在游戏之外)。

此外,您应该添加 for-loop 的左括号和右括号以提高可读性。