根据文件大小分配内存没有正确的数字?

Posted

技术标签:

【中文标题】根据文件大小分配内存没有正确的数字?【英文标题】:Allocate memory based on filesize has not the correct number? 【发布时间】:2019-04-14 11:34:02 【问题描述】:

我想将我的文件内容存储在一个动态字符串指针值中。 这是我的代码:

    char *strPtr = NULL;
    char tmpChar = "";
    inputFile = fopen(input_file, "r");

    fseek(inputFile, 0, SEEK_END);   // seek to end of file
    fileSize = ftell(inputFile);    // get current file pointer
    rewind(inputFile);
    strPtr = (char*) realloc(strPtr, fileSize * sizeof(char));
    int counter = 0;

    while ((tmpChar = fgetc(inputFile)) != EOF)
    
        strPtr[counter] = tmpChar;
        counter++;
        if (counter == fileSize)
            printf("OK!");
    
    printf("Filesize: %d, Counter: %d", fileSize,counter);

现在我的问题...使用最后一个 printf 我得到 2 个不同的值,例如:文件大小 127 和计数器 118。 另外,在我的 strPtr-Variable 的末尾有一个错误的输入,例如“ÍÍÍÍÍÍÍÍÍÍýýýýüe”。

Notepad++ 在文件末尾还说我在位置 127,那么 118 的问题是什么?

【问题讨论】:

您是否将tmpChar 声明为应有的int 没有。 char tmpChar = ""; 并以二进制模式打开 并终止 srring...请提供正确的minimal reproducible example,这还不是 什么是strPtr?它是如何声明的?它用什么值初始化,为什么要重新分配而不是分配? 【参考方案1】:

如果您在 Windows 上以文本模式(默认)打开文件,CRT 文件函数会将任何 \r\n 转换为 \n。这样做的效果是您读取的每一行都将比原来的 \r\n 短 1 个字节。

为防止此类转换,请使用“二进制”模式,通过添加“b”模式修饰符,例如“rb”。

inputFile = fopen("example.txt", "rb")

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=vs-2019

在文本模式下,回车换行组合在输入时转换为单个换行符,换行符在输出时转换为回车换行组合。

while ((tmpChar = fgetc(inputFile)) != EOF)

    strPtr[counter] = tmpChar;
    counter++;
    if (counter == fileSize)
        printf("OK!");

此外,这个循环,假设文件不包含任何 NULL 值不会终止你的字符串。如果您稍后以预期的方式使用strPtr(例如printfstrcmp 等),它将超出有效范围。

如果您确实需要一个空终止符,则需要在后面添加一个。为此,您还需要确保分配了一个额外的字节。

realloc(strPtr, (fileSize + 1) * sizeof(char));
while (...
strPtr[counter] = '\0'; // Add null terminator at end.

要处理可能包含空值的文件/字符串,您根本不能使用以空值结尾的字符串(例如,使用带有大小的memcmp 而不是strcmp)。

【讨论】:

谢谢!这解决了计数器问题!你也知道变量末尾“ÍÍÍÍÍÍÍÍÍýýýýýüe”的原因吗? 这里的“END”是什么意思,strPtr[size - 1]?我想你可能也走到了尽头。 您解决了我正在寻找的所有问题!谢谢!

以上是关于根据文件大小分配内存没有正确的数字?的主要内容,如果未能解决你的问题,请参考以下文章

C语言 读取文件到内存

分配粒度和内存页面大小(x86处理器平台的分配粒度是64K,内存页是4K,所以section都是0x1000对齐,硬盘扇区大小是512字节,所以PE文件默认文件对齐是0x200)

如何根据输入数量定义数组大小?

有关C++指针与安全阐述

linux 怎么给mysql分配内存大小

CS50 pset4 调整大小不太舒服。标题似乎已正确更新,直到我写在文件上