You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言十进制转多进制程序:数组参数无法正常写入文件问题

问题:进制转换结果数组在函数外无法正确写入文件

我编写了一段C语言代码,用于将输入的十进制数转换为二进制、十六进制和八进制(不使用格式说明符),并将结果写入文本文件。程序在终端中能正常输出转换后的各进制结果,但存储十六进制、八进制、二进制的char数组在转换函数外无法被正确访问,导致写入文本文件时这些内容为空。

相关代码

#include <stdio.h>
#include <time.h>

char *getDateAndTime();
int getInteger();
void decimalToBinary(int decValue, char binString[]);
void decimalToHex(int decValue, char hexString[]);
void decimalToOct(int decValue, char octString[]);
int saveFile(char name[], char* getDateAndTime(), int decValue, char octString[], char hexString[], char binString[]); 

int main()
{
    char binString[32];
    char octString[32];
    char hexString[32];
    char name[32];
    int decValue = 0;
    
    printf("Enter your name: ");
    fgets(name, sizeof(name), stdin);
    
    decValue = getInteger();
    if (decValue != 'x'){
        decimalToHex(decValue, hexString);
        decimalToOct(decValue, octString);
        decimalToBinary(decValue, binString);
        saveFile(name, getDateAndTime, decValue, octString, hexString, binString); 
    }
    printf("\nGoodbye!");
    return 0;
}

char *getDateAndTime()
{
    time_t t;
    time(&t);
    return ctime(&t);
}

int getInteger()
{
    char number[9];
    int num;
    int status = 1;
    do {
        printf("Enter an Integer [1-1,000,000] or type x to exit: ");
        fgets(number, sizeof(number), stdin);
        if (number[0] == 'x')
        {
            status = 0;
        }
        else 
        {
            num = atoi(number);
            if (num < 1 || num > 1000000)
            {
                printf("Error: %d is out of range\n", num);
            }
            else
            {
                status = 0;
                return num;
            }
        }
    } while (status);
    return -1;
}

void decimalToBinary(int decValue, char binString[])
{
    int quotient;
    int i = 1;
    int j;
    quotient = decValue;
    while(quotient!=0){
        binString[i++]= quotient % 2;
        quotient = quotient / 2;
    }
    printf("Decimal: %d\nBinary: ",decValue);
    for(j = i -1 ;j> 0;j--)
    printf("%d",binString[j]);
    printf("\n");
}

void decimalToHex(int decValue, char hexString[]){
    long int quotient;
    int i=1,j,temp;
    quotient = decValue;
    while(quotient!=0){
        temp = quotient % 16;
        if( temp < 10)
        temp =temp + 48;
        else
        temp = temp + 55;
        hexString[i++]= temp;
        quotient = quotient / 16;
    }
    printf("Hexadecimal: ");
    for(j = i -1 ; j> 0; j--)
    printf("%c",hexString[j]);
}

void decimalToOct(int decValue, char octString[])
{
    int quotient;
    int i = 1;
    int j;
    quotient = decValue;
    while(quotient!=0){
        octString[i++]= quotient % 8;
        quotient = quotient / 8;
    }
    printf("\nOctal: ");
    for(j = i -1 ;j> 0;j--)
    printf("%d",octString[j]);
    printf("\n");
}

int saveFile(char name[], char* getDateAndTime(), int decValue, char octString[], char hexString[], char binString[])
{
    char choice;
    int status = 1;
    printf("Save to a file? (y/n): ");
    scanf(" %c", &choice);
    while (status){
        if (choice == 'y'){
            FILE *ptr_file;
            ptr_file =fopen("G01303907_HW3.txt", "w");
            if (!ptr_file){
                return 1;
            }
            fprintf(ptr_file,"Name: %s\nDate: %s\nDecimal Value:%d\nHexadecimal String: %s\nOctal String: %s\nBinary String: %s\n",name, getDateAndTime(), decValue, hexString, octString, binString);
            fclose(ptr_file);
            status = 0;
            return 0;
        }
        else if (choice == 'n')
        {
            status = 0;
            return -1;
        }
        else{
            printf("Error: illegal value\nSave to a file? (y/n): ");
            scanf("%s", &choice);
        }
    } 
    return -1;
}

终端输出

Enter your name: Mason
Enter an Integer [1-1,000,000] or type x to exit: 23
Hexadecimal: 17
Octal: 27
Decimal: 23
Binary: 10111
Save to a file? (y/n): y

Goodbye!

生成的文本文件内容

Name: Mason
Date: Mon Oct  3 23:38:59 2022

Decimal Value:23
Hexadecimal String: 
Octal String: 
Binary String: 

请问如何解决该数组参数在自定义函数外无法正常访问的问题?


解决方案

问题核心是转换后的数组不符合C语言字符串规范,导致fprintf用%s输出时无法识别为有效字符串,具体原因和修复方法如下:

1. 二进制、八进制数组存储的是整数而非ASCII字符

decimalToBinary和decimalToOct中,直接将余数(如0、1或0-7的整数)存入char数组,但C语言字符串需要存储字符的ASCII值。例如数字0的ASCII值是'0'(即48),而非整数0。

修复方法:将余数转换为对应ASCII字符,即加上'0'。

2. 所有转换数组缺少字符串终止符'\0'

C语言字符串必须以'\0'作为结尾标记,否则%s输出时会从数组起始位置一直读取,直到找到'\0',导致读取垃圾数据或识别为空。

修复方法:转换完成后在数组末尾添加'\0'。

3. 转换结果逆序存储且起始索引从1开始

原代码从索引1开始存储余数,最后反向输出,但数组起始位置(索引0)未初始化,且整体逆序,导致字符串读取异常。

修复方法:从索引0开始存储逆序余数,完成后反转数组得到正确顺序,再添加终止符。

修改后的关键函数代码

decimalToBinary 函数

#include <string.h> // 需要添加此头文件用于字符串操作

void decimalToBinary(int decValue, char binString[])
{
    int quotient = decValue;
    int i = 0;
    // 处理输入为0的特殊情况
    if (decValue == 0) {
        binString[i++] = '0';
        binString[i] = '\0';
        printf("Decimal: %d\nBinary: %s\n", decValue, binString);
        return;
    }
    // 逆序存储余数的ASCII字符
    while(quotient != 0){
        binString[i++] = (quotient % 2) + '0';
        quotient = quotient / 2;
    }
    // 添加字符串终止符
    binString[i] = '\0';
    // 反转数组得到正确顺序
    int start = 0, end = i - 1;
    char temp;
    while (start < end) {
        temp = binString[start];
        binString[start] = binString[end];
        binString[end] = temp;
        start++;
        end--;
    }
    printf("Decimal: %d\nBinary: %s\n", decValue, binString);
}

decimalToOct 函数

void decimalToOct(int decValue, char octString[])
{
    int quotient = decValue;
    int i = 0;
    // 处理输入为0的特殊情况
    if (decValue == 0) {
        octString[i++] = '0';
        octString[i] = '\0';
        printf("\nOctal: %s\n", octString);
        return;
    }
    // 逆序存储余数的ASCII字符
    while(quotient != 0){
        octString[i++] = (quotient % 8) + '0';
        quotient = quotient / 8;
    }
    // 添加字符串终止符
    octString[i] = '\0';
    // 反转数组得到正确顺序
    int start = 0, end = i - 1;
    char temp;
    while (start < end) {
        temp = octString[start];
        octString[start] = octString[end];
        octString[end] = temp;
        start++;
        end--;
    }
    printf("\nOctal: %s\n", octString);
}

decimalToHex 函数

void decimalToHex(int decValue, char hexString[]){
    long int quotient = decValue;
    int i = 0, temp;
    // 处理输入为0的特殊情况
    if (decValue == 0) {
        hexString[i++] = '0';
        hexString[i] = '\0';
        printf("Hexadecimal: %s", hexString);
        return;
    }
    // 逆序存储十六进制字符的ASCII值
    while(quotient != 0){
        temp = quotient % 16;
        if(temp < 10)
            temp = temp + '0'; // 用字符常量代替数字,可读性更强
        else
            temp = temp + 'A' - 10;
        hexString[i++] = temp;
        quotient = quotient / 16;
    }
    // 添加字符串终止符
    hexString[i] = '\0';
    // 反转数组得到正确顺序
    int start = 0, end = i - 1;
    char tempChar;
    while (start < end) {
        tempChar = hexString[start];
        hexString[start] = hexString[end];
        hexString[end] = tempChar;
        start++;
        end--;
    }
    printf("Hexadecimal: %s", hexString);
}

额外修复点

  • 添加<string.h>头文件,用于字符串操作;
  • 修正getInteger函数的返回值逻辑,避免未定义行为;
  • 处理输入字符串中的换行符,避免写入文件时出现多余空行;
  • 修正saveFile中scanf的格式,避免缓冲区溢出。

修改后,数组会被正确识别为C语言字符串,写入文件时就能正常显示转换结果。


内容的提问来源于stack exchange,提问作者Noname

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 06:50:24