【问题标题】:Writing data read with read () to int array in C将用read()读取的数据写入C中的int数组
【发布时间】:2020-11-27 14:29:50
【问题描述】:

我有一个文件,每行都有数字。我正在尝试使用 read() 函数将从文件中读取的数据写入 int 数组。我可以读取文件并将其打印到终端。我怎样才能得到我读入 arr 数组的数字?

这是我的代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

int main() {
    int len, fd,arr[10000],i=0;
    fd = open("1.txt", O_RDONLY);
    if (fd >= 0) {

        while(read(fd, &len, sizeof(int)) > 0){
            write(1, &len, sizeof(int));

        }
    }

    close(fd);

    return 0;
}

【问题讨论】:

  • 你的意思是要读取文本文件,其中的数字是用字符串表示的?
  • 是的,然后我想在读完后写入数组
  • read(fd, arr, len * sizeof *arr)。直接读入数组即可。无需阅读和复制。
  • 但是read(fd, &amp;len, sizeof len) 真的是你想要的吗?如果这是一个文本文件,那很可能不是你想要的。
  • 你几乎肯定想要fread/strtolscanf的味道

标签: c file posix low-level-io


【解决方案1】:

在大多数(全部?)实现中,整数将数字的二进制表示形式存储在该整数的位和字节中。另一方面,字符串和文本文件之类的内容使用字节来存储数字、空格和换行符的 ASCII 值。

int(假设 4 字节,每个 8 位,大端)可以这样存储值 1234:

Address   0x42  0x43  0x44  0x45
Value     0x00  0x00  0x04  0xD2
Text       NUL   NUL   EOT    Ò

另一方面,字符串可以包含代表文本的每个字符的 ASCII 值。字符串“1234”可以这样存储:

Address   0x82  0x83  0x84  0x85  0x86
Value     0x31  0x32  0x33  0x34  0x00
Text        1     2     3     4    NUL

当您进行读取时,您会读取文本文件的字符。将它们读入char 数组很容易,您无需进行任何对话,只需在末尾添加 NUL-Byte。当你想得到数字时,你必须把它们从一个字符串中转换出来。

这意味着您必须读取文件,如果需要,您可以使用 read() 执行此操作,并将内容存储在 char 数组中,添加 NUL 字节,然后使用类似的函数转换结果字符串strtol()sscanf()

你在做什么

您所做的是将 ASCII 字符读入 int len。在write() 调用之前使用调试器时,可以检查len 的值。就我而言,我将其用作输入文件:

0
1
2
3
...

当我在write() 之前停止调试器时,我看到len 的值是170986032 == 0xA310A30。我的系统是小端的,意味着最低字节存储在最低地址(与我之前的示例不同)。这意味着首先出现0x30,然后是0x0a0x310x0A。 由此我们知道我们得到了len的如下内存布局。

Address Offset   0x00  0x01  0x02  0x03
Value            0x30  0x0A  0x31  0x0A
Text                0    LF     1    LF

如您所见,文本被解释为int

如何得到你想要的

您希望将数据存储到char 数组中。然后解析它。我使用一些伪代码来更好地解释它。这不是 C 代码。您应该学习编写自己的代码。这只是为了让您了解您必须做什么:

char buffer[<buffersize>] //create a buffer array
r=read(buffer) //read the file into the buffer. You may need to repeat that multiple times to get everything
if r==error //check for errors
  <do some error handling here>
buffer[<one after the last read byte>]='\0' //add the NUL-Byte st the end, so that we have a string.
int values[<number of ints you want>]  //create an array to store the parsed values
for(<one loop for every int>) //make the loop for every int, to parse the int
  values[<index>]=strtol(buffer,&buffer,0) //parse the text to a int
  if error occured:
    <do some error handling here>

如何在 C 中实现这一点是您的任务。请记住缓冲区大小,以免以 UB 结尾。

【讨论】:

    【解决方案2】:
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <fcntl.h>
    #include <errno.h>
    
    int main()
    {
        int fd;
        char arr[10000];
        int arr2[10000];
        ssize_t count;
        fd = open("1.txt", O_RDONLY);
        if (fd >= 0)
        {
            count = read(fd, arr, 10000); // reading from file and writing to array.
            if (count == -1)
            {
                printf("Error %d\n", errno);
                exit(0);
            }
            arr[count] = '\0';
        }
    
        for(int i=0; i<count; i++)  //Converting the character arrays to integer array
        {
            if(arr[i] >='0' && arr[i]<='9' )
            arr2[i] = arr[i]-'0';
            else
            {
                arr2[i] = 0; //For characters other than numbers.
            }
            
        }
    
        for (int i=0; i<count; i++)
        {
            printf("%d ",arr2[i]);
        }
    
        close(fd);
    
        return 0;
    }
    

    在这里,我从文件中读取数字并存储到字符数组中,然后将其转换为整数数组。如果有数字以外的任何字符,我在数组中将其分配为零。

    【讨论】:

    • 我以前试过这个,不幸的是它不起作用
    • 是的。但数组应该是整数
    • 当输入文件是文本文件时,它不会那样工作,因为它是。只有当输入是包含二进制形式的int 的二进制文件时,它才会起作用。在这种情况下,您必须将数字乘以sizeof(int)。你必须检查返回值。
    • @KrishnaKanthYenumula 它仍然不适用于文本文件。您的解决方案现在适用于格式正确的二进制文件。除此之外,您仍然不检查返回值。无论如何,如果不完全重写大部分代码,您的代码将无法完成任务。
    • @KrishnaKanthYenumula 您单独解释每个字符和数字,但像 42 这样的数字使用两个数字。您使用的int 实际上并不存储该号码。每个不是数字的字符都会导致 arr2 中的空白,其中未设置导致 UB 的元素。
    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    相关资源
    最近更新 更多