【问题标题】:printing digits of a number in textual format以文本格式打印数字的数字
【发布时间】:2014-09-20 21:27:41
【问题描述】:

所以我一直在尝试用 c 编写这段代码,其基本思想是用户输入一个正整数,程序打印该数字中的数字,我已经递归地完成了,但事情是,当我编译它时,我没有收到任何错误,但输出只是一些垃圾,另一方面,我尝试过调试,所以我设置了一些断点,我一直得到很好的结果,调试时输出正确,与尝试编译完全相同的代码时不同 如果有人知道为什么会这样,将不胜感激

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

char *numToWord (int number){
    char *newDigit = NULL;
    switch(number){
    case 0:
        newDigit = malloc (5*sizeof(char));
        sprintf(newDigit,"zero");
        break;
    case 1:
        newDigit = malloc (4*sizeof(char));
        sprintf(newDigit,"one");
        break;
    case 2:
        newDigit = malloc (4*sizeof(char));
        sprintf(newDigit,"two");
        break;
    case 3:
        newDigit = malloc (6*sizeof(char));
        sprintf(newDigit,"three");
        break;
    case 4:
        newDigit = malloc (5*sizeof(char));
        sprintf(newDigit,"four");
        break;
    case 5:
        newDigit = malloc (5*sizeof(char));
        sprintf(newDigit,"five");
        break;
    case 6:
        newDigit = malloc (4*sizeof(char));
        sprintf(newDigit,"six");
        break;
    case 7:
        newDigit = malloc (6*sizeof(char));
        sprintf(newDigit,"seven");
        break;
    case 8:
        newDigit = malloc (6*sizeof(char));
        sprintf(newDigit,"eight");
        break;
    case 9:
        newDigit = malloc (5*sizeof(char));
        sprintf(newDigit,"nine");
        break;
    }
    return newDigit;
}

char * writeAbsolute (int number) {
    char * word = NULL; // variable where the return value will be stored, must clean in main part
    int digit;
    digit = number % 10;
    if (number){
        number /= 10;
        word = writeAbsolute (number);
        char *newDigit = NULL;
        char *newWord = NULL;
        newDigit = numToWord(digit);
        if (word){
            int numOfLetters = (int)( strlen(newDigit)+strlen(word) );
            newWord = (char*) malloc(numOfLetters * sizeof(char));
            sprintf(newWord,"%s %s",word,newDigit);
            word = newWord;
        }
        else{
            word = newDigit;
        }
        free (newWord);
        free (newDigit);
    }
    return word;
}


int main() {
    int number;
    char * word;
    printf("Enter an integer:\n");
    scanf("%d",&number);
    word = writeAbsolute(number);
    printf("%s",word);
    return 0;
}

【问题讨论】:

  • 首先,字符串以 NULL 结尾(与尾随空格不同)[检查您的大小]。
  • 另外,必须链接到Do I cast the result of malloc
  • 谢谢,我删除了那些不必要的 malloc 铸件并将这些“一”、“二”、“三”...更改为“一”、“二”、“三”...并修复了它们的大小分别(除了字符串的长度之外,我仍然必须分配额外的 sizeof(char) 内存,用于每个字符串末尾的 '\0',对吗?),但是作为那些无论如何,尾随空格只是为了打印格式,我没有改变,仍然得到一些垃圾输出
  • 我正在写一个答案,但这与strlen() 的返回有关,它返回字符串中最多但不包括NULL 终止符的字符数。如果你愿意,你仍然可以用空格填充字符串,只要确保为 NULL 终止符留出足够的空间。
  • 注意:我因为分心(饥饿的猫)而放弃了我的答案,并且抽签速度很慢。接受的答案还考虑到sizeof(char)==1 和您在word 上对free() 的调用。

标签: c debugging recursion compiler-errors


【解决方案1】:

第一个问题是您没有为所有字符串分配足够的内存。由于固有的尾随'\0' 终止字节,字符串"1234" 应分配5 个字符。只需在所有字符串分配长度中添加至少一个:

newDigit = malloc(5*sizeof(char));
sprintf(newDigit,"six ");
...
int numOfLetters = (int) (strlen(newDigit) + strlen(word) + 1);

还要注意sizeof(char) 被定义为1

第二个问题是你在这段代码中使用它们后立即释放你的字符串:

if (word) {
    ...
    newWord = (char *) malloc(...);
    ...
    word = newWord;
}
else {
    word = newDigit;
}

free (newWord);
free (newDigit);

假设word 不是NULL,当你最后释放newWord 时,word 变得无效,因为它只是指向同一个字符串。因此,下次您尝试使用 word 时,您会通过尝试使用先前释放的内存来调用未定义的行为。

在这种情况下,您可能想要的是:

if (word) {
    int numOfLetters = (int)( strlen(newDigit)+strlen(word) + 1);
    newWord = (char*) malloc(numOfLetters);
    sprintf(newWord,"%s%s", word, newDigit);
    word = newWord;
    free(newDigit);
}
else {
    word = newDigit;
}
// Don't free anything else here

【讨论】:

  • 非常感谢你们两位!是我不应该做的释放导致了所有的麻烦,下次我必须更加小心我可以释放哪些内存以及我仍将使用哪些内存。我投票给你的答案,再次感谢
猜你喜欢
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-31
  • 1970-01-01
  • 2015-11-28
相关资源
最近更新 更多