c - 用C读取和写入二进制文件

标签 c pointers scanf binaryfiles file-pointer

这是 2 个独立的应用程序。

  • 在第一个中,我尝试在名为 emp.bin 的二进制文件中存储员工详细信息,如姓名、年龄和薪水。 .
  • 在第二个应用程序中,我试图查看文件的内容,但在名称的位置,只出现了第一个字符。

  • 我尝试分别打印每个字符,结果发现名称中的每个字母后面都有 3 个空字符 '\n',这就是它不在第一个字符后面打印的原因。

    “编写”应用程序代码:
    //Receives records from keyboard and writes them to a file in binary mode
    #include <stdio.h>
    
    int main()
    {
        FILE *fp;
        char another = 'Y';
        struct emp
        {
            char name[40];
            int age;
            float bs;
        };
        struct emp e;
        fp = fopen("emp.bin", "wb");
        if (fp == NULL)
        {
            puts("Cannot open the file.");
            return 1;
        }
        while(another == 'Y')
        {
            printf("Enter the employee name, age and salary: ");
            scanf("%S %d %f", e.name, &e.age, &e.bs);
            while(getchar() != '\n');
            fwrite(&e, sizeof(e), 1, fp);
            printf("Add another record? (Y/N)");
    
            another = getchar();
        }
        fclose(fp);
        return 0;
    }
    

    “读取”应用程序代码:
    //Read records from binary file and displays them on VDU
    #include <stdio.h>
    #include <ctype.h>
    
    int main()
    {
        FILE *fp;
        struct emp
        {
            char name[40];
            int age;
            float bs;
        } e;
        fp = fopen("emp.bin", "rb");
        if (fp == NULL)
        {
            puts("Cannot open the file.");
            return 1;
        }
        while (fread(&e, sizeof(e), 1, fp) == 1)
        {
            printf("\n%s \t %d \t $%.2f\n", e.name, e.age, e.bs);
        }
        fclose(fp);
    }
    

    这是输入和输出:

    enter image description here
    enter image description here

    如何更正此代码以使其打印全名?

    最佳答案

    问题出在“编写器”应用程序中,甚至在执行实际写入之前。

    当你从用户那里得到数据时

    scanf("%S %d %f", e.name, &e.age, &e.bs);
    

    您使用格式 %S (大写字母“S”。格式说明符是 区分大小写 !)。正如我们在 printf man page 中所读到的那样

    S
    (Not in C99, but in SUSv2.) Synonym for ls. Don't use.



    这将我们带到 %ls以下列方式描述的格式说明符

    s
    [...] If an l modifier is present: The const wchar_t * argument is expected to be a pointer to an array of wide characters. Wide characters from the array are converted to multibyte characters



    Windows source我们有:

    S
    Opposite-size character string, up to first white-space character (space, tab or newline). [...]
    When used with scanf functions, signifies wide-character array; when used with wscanf functions, signifies single-byte-character array [...]



    因此,基本上,您是从 stdin 读取字符并将它们转换为 宽字符 .在这种情况下,每个字符都需要 sizeof(wchar_t) .可能在您的系统中,此大小为 4。

    您需要的只是%s格式说明符。并且由于您的 name数组大小为 40,我建议使用
    scanf("%39s", e.name );
    

    从用户那里获取名称。这样最多可以写入 39 个字符,第 40 个字符保留给字符串终止符 '\0' .

    关于c - 用C读取和写入二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61957595/

    相关文章:

    c - getchar() 会导致错误,而 scanf 不会

    go - fmt.Scanf 在 Go 中无法正常工作

    c++ - c和c++混合

    c++ - C/C++ 中的高级指针类型转换

    c - 读取多行输入并将整数保存到数组中

    带函数和金钱的c指针

    c++ - 如何在声明后为 unique_ptr 赋值?

    c - 检查重复 if 语句条件的更好方法

    c - 如何在shell脚本中使用ctrl+c?

    c - 如何在 WSL2 上正确安装 perf 命令