【问题标题】:Printing string gives bytes C [duplicate]打印字符串给出字节 C [重复]
【发布时间】:2018-11-07 19:51:36
【问题描述】:

当我编写简单的代码将简单的字母序列编码为字节并再次解码时,我遇到了解码问题。一切都在完成我想要4个字符的序列,但它最后还包括字节。这是我的代码:

char* B2T(int num) {
    unsigned char temp;
    char res[4];
    int sw[] = { 6,4,2,0 };
    char tab[4] = { 'A', 'C', 'G', 'T' };
    int i = 0;
    for (int i = 0; i < 4; i++) {
        res[i] = tab[(num >> sw[i]) & 3];
    }
    printf_s("%s\n", res); //!!!!!!problem here!!!!!!!!
    return res;
}

int main() {
    FILE *I, *O;
    char tab[5], opt;
    int res, i, temp;
    bool work = true;
    while (work) {
        printf_s("\nChoose option: decode or encode (d/e): ");
        scanf_s("%c", &opt);
        switch (opt) {
        case 'e':
            fopen_s(&I, "DNA.txt", "r");
            fscanf_s(I, "%s", &tab, 5);
            fopen_s(&O, "result.bin", "a");
            while (feof(I) == 0) {
                res = T2B(tab);
                printf_s("%X ", res);
                fprintf_s(O, "%X ", res);
                fscanf_s(I, "%s", &tab, 5);
            };
            fclose(I);
            fclose(O);
            break;
        case 'd':
            fopen_s(&I, "result.bin", "r");
            fscanf_s(I, "%X", &temp);
            while (feof(I)==0) {
                char* ress = B2T(temp);
                fscanf_s(I, "%X", &temp);
            }
            fclose(I);
            break;
        }
    }
    return 0;
}

【问题讨论】:

  • 这是 C 还是 C++?请不要标记两种不同的语言。而在 C 中,字符串必须以空值结尾。最后一个字符必须是\0
  • @Ron 代码看起来像 C,而不是 C++
  • 能否提供样例输入输出?
  • 你会想看看Why is while ( !feof (file) ) always wrong?。 (这解释了你的额外角色)

标签: c arrays string printf


【解决方案1】:

您的 res 不是以空值结尾的。

改成:

char res[5];
res[4] = '\0';

那么printf就会正确打印出来了。

【讨论】:

    【解决方案2】:

    您填充char res[4];,但没有以空值终止它,这会导致未定义行为,因为printf() 期望空值终止符号停止打印。

    改为这样做:

    char res[5];
    res[4] = '\0';
    

    此外,你应该关注这一行:

    while (feof(I) == 0)
    

    在循环中使用feof() 来停止解析文件。这是一个已知问题,它解释了您的额外角色。请阅读Why is “while ( !feof (file) )” always wrong?


    PS:通常 C 库的所有函数都希望字符串以空值结尾,因此强烈建议您的所有字符串都以空值结尾。

    【讨论】:

      【解决方案3】:

      哎呀!其他人已经说过错误的输出是由未以 null 终止的 char 数组引起的。

      但是您的代码包含另一个(恕我直言)缺陷:您正在从函数返回一个自动数组:

      char* B2T(int num) {
          unsigned char temp;
          char res[4];              // <- res will reach end of life when function returns
          ...
          return res;
      }
      
      int main() {
          FILE *I, *O;
          char tab[5], opt;
          int res, i, temp;
          ...          
                      res = T2B(tab);  // <- res is a dangling pointer converted to int
          ...
      

      在数组达到生命周期结束后使用指向数组的指针是明确的未定义行为。在常见的实现中,自动数组存储在堆栈中,并且在函数返回导致意外更改后可以重用其内存。 Google for C 悬空指针 以获取更多参考...

      一个快速的解决方法是将其声明为静态,这在这里可以接受,因为您既不使用递归也不使用多线程:

      char* B2T(int num) {
          unsigned char temp;
          static char res[5];              // <- res will persist after function returns
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-01
        • 1970-01-01
        • 2017-02-02
        • 2016-03-09
        • 1970-01-01
        • 1970-01-01
        • 2019-04-09
        • 2014-02-01
        相关资源
        最近更新 更多