无法将int打印到文件中

时间:2017-02-20 09:55:07

标签: c file pipe

我正在尝试在文件上打印int array,但它给了我一个错误。

write_error:Bad address.

我的int array类似于:

1 2 3 4 5 6 7 8 9 

我想在file上打印如下:

1 2 3
4 5 6 
7 8 9

这是我正在使用的代码:

void printToFile(int listBoard[]) {
  int file_write;
  char buffer[100];
  char buffer2[10];
  if ((file_write = open("./board.txt", O_WRONLY | O_CREAT | O_TRUNC, 0700)) < 0) {
    err_sys("error output file");
  }
  if (write(file_write, snprintf(buffer2, 10, "%d",listBoard[2]), 18) != 18){
    err_sys("write_error");
  }
  if (close(file_write) != 0){
    err_sys("error close write");
  }
}

我也尝试了(char),但它将int转换为ascii char

你能告诉我我错过了什么吗?

修改

我的文件输出是:

3@\00\00펈㰙\00ጠ

编辑代码:

void printToFile(int listBoard[]){

  int file_write;
  char buffer[100];
  int value;
  int cont = 0;
  char buffer2[10];
  if ((file_write = open("./board.txt", O_WRONLY | O_CREAT | O_TRUNC, 0700)) < 0) {
      err_sys("error output file");
  }
  int len = snprintf(buffer2, 10, "%d", listBoard[2]);
  if (write(file_write, buffer2, len) != len) {
      err_sys("write_error");
  }
  if (close(file_write) != 0) {
      err_sys("error close write");
  }

}

输出文件:

3

上次编辑

这就是我现在用它来打印它作为我想要的输出

if ((file_write = open("./board.txt", O_WRONLY | O_CREAT | O_TRUNC, 0700)) < 0) {
    err_sys("error output file");
}
for (int index = 0; index < SIZE_BOARD; index++) {
    if (cont == 3) {
        int len = snprintf(buffer2, 1, "%d \n", ' ');
        if(write(file_write, buffer2, len) != len) {
            err_sys("write_error");
            cont=0;
        }
    }
    int len = snprintf(buffer2, 10, "%d ", listBoard[index]);
    if (write(file_write, buffer2, len) != len) {
        err_sys("write_error");
        cont++;
    }
}

if(close(file_write) != 0) {
    err_sys("error close write");
}

但它没有正确地执行\n。我缺少什么?

5 个答案:

答案 0 :(得分:3)

写的定义如下:

ssize_t write(int fd, const void *buf, size_t count);

snprintf的定义如下:

int snprintf(char *str, size_t size, const char *format, ...);

现在,您正在将snprintf提供给期望void *buf的写入位置。即数据所在的地址。

所以你必须做

snprintf(buffer2, 10, "%d", listBoard[2]);

然后

write(file_write, buffer2, 18);

修改

这将修复语法错误。从语义上讲,您可以看到您正在向缓冲区2写入10个字节,但您要将18写入文件。这将用垃圾填充文件。所以我建议。

int len = snprintf(buffer2, 10, "%d", listBoard[2]);
write(file_write, buffer2, len);

编辑2:

int len = snprintf(buffer2, 1, "%d \n", ' ');

首先,您的格式说明符具有 3 字节,而您只将 1 字节写入缓冲区2。第二,为什么你的论点' '当你应该给listBoard[n]

答案 1 :(得分:2)

使用dprintf()将格式化的字符串写入文件:

dprintf(file_write, "%d", listBoard[2]);

dprintf将为您处理所有写入内容,因此这是您打开和关闭时唯一需要的调用。

dprintf是文件描述符的fprintf。更多信息:https://linux.die.net/man/3/dprintf

答案 2 :(得分:0)

snprintf (and family) functions会返回整数

write调用中使用此整数作为指向缓冲区的指针。这将导致未定义的行为

单独调用snprintf,然后将buffer2作为第二个参数传递。并使用strlen获取buffer2中字符串的实际长度,而不是硬编码将导致从外部读取的幻数18 -bounds和 UB的另一个案例。

答案 3 :(得分:0)

首先,snprintf返回一个整数,该整数是字符串未被截断时已写入的字符数(正如您可以在snprintf manual上看到的那样)

您无法在write命令中使用它。然后您可以使用:

 if ( snprintf(buffer2, 10,"%d",listBoard[2]) >= 10 ) {
    /* handle truncation error*/
 }
 if(write(file_write,buffer2,18)!=18){
     err_sys("write_error");

无论如何,因为buffer2最多10个字符,你为什么要写18个字节?

其他可能的错误:对于空终止,buffer2应该至少为10 + 1字节。

答案 4 :(得分:0)

您永远不会指定必须使用原始文件描述符,因此,让我们将您的代码上移一级到C标准库的myEq (x:xs) (y:ys) = if x == y then myEq xs ys else False 抽象。它更容易使用。

FILE

请注意,这使用循环来迭代板数组的元素,这似乎是原始代码中缺少的,也是您使用它的部分问题。

打印:

void printToFile(const int listBoard[]) {
  FILE * const out = fopen("board.txt", "wt");
  if (out == NULL) {
    err_sys("error output file");
  }
  for(int j = 0; j < 3; ++j) {
    for (int i = 0; i < 3; ++i)
      fprintf(out, "%d ", listBoard[3 * j + i]);
    fprintf(out, "\n");
  }
  fclose(out);
}
由于我很懒,每条线上都有一个尾随空间,但希望这很好。我也省略了一些内部错误检查。