【问题标题】:Filling buffer, passed as argument by address填充缓冲区,按地址作为参数传递
【发布时间】:2013-11-20 13:18:19
【问题描述】:

我遇到了一个相当简单的任务的问题:我想在函数中读取一个文件,该函数将指向缓冲区的指针作为其参数之一。在函数中,缓冲区应该与文件的内容一起归档,内容将在函数外部使用。

但是,它在readFile() 内部显示的内容不正确,在readFile 外部显示更多垃圾。此外,我想以十六进制(%02x)显示文件的内容,但我不知道如何。我正在为指针的东西而苦苦挣扎。你能帮帮我吗?

uint8_t *buffer;

int main(int argc, char *argv[]){
    uint32_t i = 0;
    unsigned long fileLen;

    // Read file
    fileLen = readFile(argv[2], &buffer);
    printf("Buffer afterward: %s\n", &buffer);
} 
unsigned long readFile(char *fileName, uint8_t *buffer){
    unsigned long fileLen = 0;
    uint8_t i;

    FILE *file;
    file = fopen (fileName, "r");  /* open the file for reading */ 

    if(file==NULL){
        printf("Error reading %c.\n", fileName);
    return 0;
    }
    fseek(file, 0, SEEK_END);
    fileLen=ftell(file);
    fseek(file, 0, SEEK_SET);
    *buffer=malloc(fileLen+1);

    if(!buffer)
    {
            fprintf(stderr, "Memory error!");
            fclose(file);
            return;
    }
    fread(&buffer, fileLen, 1, file);

    printf("Source message (%s, %ld bytes):\n%s\n", fileName, fileLen, &buffer);
    puts("\n");
    fclose(file);

    return fileLen;
}

这是输出:

´源消息(bla,16 字节): 废话少说 1234 � ſ� ſUJZ�����

后缓冲:p`

如果bla的内容是:

blablablub
1234

【问题讨论】:

  • buffermain中是如何定义的?
  • 抱歉,忘记将其包含在代码中。已添加。

标签: c file pointers


【解决方案1】:

如果您要在 readFile 函数中分配缓冲区,则假定 buffer 是通过引用而不是值传递的。那就是:

unsigned long readFile(char *fileName, uint8_t **buffer);

所以当你为它分配内存时,你使用malloc()并将得到的地址存储到*buffer,但是为了测试分配是否成功,你必须测试*buffer,而不是buffer。那就是:

if(!*buffer)
{
        fprintf(stderr, "Memory error!");
        fclose(file);
        return;
}

对于函数的其余部分,您将使用*buffer,而不是buffer

fread(*buffer, fileLen, 1, file);

printf("Source message (%s, %ld bytes):\n%s\n", fileName, fileLen, *buffer);
puts("\n");
fclose(file);

【讨论】:

    【解决方案2】:

    有点令人困惑,因为您说 which takes a pointer to a buffer as one of its arguments 但实际上您并没有将指针传递给缓冲区,而是将指针传递给整数(用作指针,实际上是双指针)。

    就个人而言,我更喜欢在读取函数之外进行分配,这样就不会转移所有权(使内存管理更容易)。比如:

    unsigned long readFile(char *fileName, unsigned char *buffer, uint8_t bufferSize){
    
        // -- read at most x number of bytes (bufferSize) from the file to buffer
    
        // -- return number of bytes read
        return fileLen;
    }
    

    但要回答您的问题,并不是您按值传递指针,指针应该是正确的,只是您的 printf 语句是错误的。这:printf("Buffer afterward: %s\n", &buffer); 应该类似于:printf("Buffer afterward: %s\n", (char*)buffer);

    【讨论】:

      【解决方案3】:

      我已经稍微调整了你的代码:

      /**
       * in order to allocate the buffer inside the function you need
       * to pass the address to the pointer
       */
      unsigned long readFile(char *fileName, uint8_t **buffer)
      {
        unsigned long fileLen = 0;
        uint8_t i = 0;
        char* ch = NULL;
        /* open the file in binary mode to get exact content
           otherwise the fileLen will be wrong */ 
        FILE *file = fopen (fileName, "rb");  
      
        if (file==NULL)
        {
          perror(fileName);
          return 0;
        }
        fseek(file, 0, SEEK_END);
        fileLen=ftell(file);
        fseek(file, 0, SEEK_SET);
      
        *buffer=malloc(fileLen+1);
      
        if(!*buffer)
        {
          fprintf(stderr, "Memory error!");
          fclose(file);
          return;
        }
      
        /* read into the buffer, note the * in front of the buffer */
        fread(*buffer, fileLen, 1, file);
      
        /* since you do not know what is in the buffer, the following printf is a bit
           risky, you cannot be sure that the buffer is terminated by a \0 
           printf("Source message (%s, %ld bytes):\n%s\n", fileName, fileLen, *buffer); */
        /* instead do something like this */
        printf( "Source nessage (%s, %ld bytes):", fileName, fileLen );
        for (ch = *buffer ; *ch < *buffer + fileLen; ++ch)
        {
          /* if you want the output in hex */
          printf( "%02X", *ch );
        }
        fclose(file);
      
        return fileLen;
      }
      

      【讨论】:

        猜你喜欢
        • 2013-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-20
        • 2012-05-11
        • 2013-02-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多