fgetc()读取0c符号并且数组元素无效?为什么会这样?

时间:2016-10-19 06:30:00

标签: c++ arrays

我注意到有趣的事情,但我不确定它是否应该以这种方式发生。

我得到了一些使用fgetc()的代码;从文件中读取符号并将它们存储到int中l;

  l=fgetc(file); 

文件以读二进制模式打开(“rb”);使用

  file=fopen("filename", "rb");

然后使用字符串流将每个符号转换为十六进制格式并发送到字符串中,然后存储在char数组中;

  std::stringstream sl;


  sl << std::hex << l; sl >> sll; 

  char as[i]=sll[i];

问题是当fgetc();读取ascii表中的符号表示为十六进制格式的 OC FF 作为char我的最终字符数组填充为0。

简而言之,如果char []元素包含0c,则其余元素为0;

我不知道为什么会这样。当我使用十六进制编辑器编辑我的文件并用其他东西替换0c时。该文件已正确读取,所有符号在文件中写入时都存储在数组中。

如果你能说出如何规避这些行为,我将不胜感激。

确定。完整代码:

#include <stdio.h>
#include<iostream>
#include <string.h>
#include "u.c"
#include <wchar.h>
#include <sstream>

int main() {
    unsigned long F, K;
    std::string k;
    char hhh[300];
    char hh1[300];
    char kk[64];
    int lk;

    memset(kk, 0, 64);

    FILE *diy; 
    FILE *ydi;

    std::cin >> k;
    std::cin >> hhh;
    std::cin >> hh1;
    lk = k.length();

    for (int i = 0; i < lk; i++) {
        kk[i] = k[i];
    }

    ;
    bof(kk, lk);
    diy = fopen(hhh,"rb");
    ydi = fopen(hh1,"wb");

    int mm = 0;
    int l;
    int r;
    char ll[9];
    char rr[9];

    memset(ll, 0, 9);
    memset(rr, 0, 9);

    std::string sll; 
    std::string slr; 
    char sL[3];
    char sR[3];
    int i = 0;

    while (!feof(diy)) {
        l = fgetc(diy);
        r = fgetc(diy);

        std::stringstream sl;
        std::stringstream sr;

        sl << std::hex << l;
        sl >> sll;
        sL[0] = sll[0];
        sL[1] = sll[1]; 
        sr << std::hex << r;
        sr >> slr;
        sR[0] = slr[0];
        sR[1] = slr[1]; 

        if (i == 0) {
            ll[0] = sL[0];
            ll[1] = sL[1];
            ll[2] = sR[0];
            ll[3] = sR[1];
            sL[0] = '\0';
            sR[0] = '\0';
            sL[1] = '\0';
            sL[1] = '\0';
        }

        ;

        if (i==1) { 
            ll[4] = sL[0];
            ll[5] = sL[1];
            ll[6] = sR[0];
            ll[7] = sR[1];
            sL[0] = '\0';
            sR[0] = '\0';
            sL[1] = '\0';
            sL[1] = '\0';
        }

        ;

        if (i == 2) {
            rr[0] = sL[0];
            rr[1] = sL[1];
            rr[2] = sR[0];
            rr[3] = sR[1];
            sL[0] = '\0';
            sR[0] = '\0';
            sL[1] = '\0';
            sL[1] = '\0';
        }

        ;

        if(i==3){
            rr[4] = sL[0];
            rr[5] = sL[1];
            rr[6] = sR[0];
            rr[7] = sR[1];
            sL[0] = '\0';
            sR[0] = '\0';
            sL[1] = '\0';
            sL[1] = '\0';
        }

        ;

        sL[0] = '\0';
        sR[0] = '\0';
        sL[1] = '\0';
        sL[1] = '\0';

        if (i == 3) {
            printf(" %s %s \n ", ll, rr); //indicated that my rr array had problems with that 0x0c;
            sscanf(ll, "%08lX", &F);
            sscanf(rr,"%08lX",&K); 
            printf(" before %08lx %08lx \n ", F, K);
            omg( &F, &K);
            printf(" after %20lx %20lx \n ", F, K);
            memset(ll, 0, 9);
            memset(rr, 0, 9);

            char RR[9];

            sprintf(RR, "%08lx", F); 

            char LL[9];

            sprintf(LL, "%08lx", K);
            printf(" %s %s ", LL, RR);

            for (int j = 0; j < 4; j++) {
                char ls[3];

                ls[0] = LL[j*2];
                ls[1] = LL[2*j+1];

                int kj; 

                std::stringstream op;
                op << ls;
                op >> std::hex >> kj;
                fputc(kj, ydi);
            }

            ;

            for(int j = 0; j < 4; j++) {
                char lr[3];

                lr[0] = RR[j*2];
                lr[1] = RR[2*j+1];

                int kjm; 

                std::stringstream ip;
                ip << lr;
                ip >> std::hex >> kjm;
                fputc(kjm,ydi);        
            }

            ;

            memset(LL, 0 ,9);
            memset(RR, 0, 9);
        }

        ;
        i++;
        std::cout << "\n";

        if (i == 4) {
            i = 0;
        }

        ;
    }

    ;

    fclose(diy);
    fclose(ydi);
}

;

既然你问过,现在你拥有它。

  1. 此代码无法编译,因为您没有必要的库。
  2. 简化代码在本文的开头。
  3. 您没有的那些图书馆与此问题无关。

2 个答案:

答案 0 :(得分:2)

核心问题

你认为

std::stringstream the_stream;
std::string the_string;

the_stream << std::hex << 0x0C;
the_stream >> the_string;

结果the_string包含"0c"。但是,它将包含"c"

这意味着稍后您最终会将输入"\x0c\xfe"转换为'c', '\0', 'f', 'e'。如果你在C风格的字符串中的任何一点使用它,当然它会在c之后结束字符串。

调试此程序非常困难。将来,请编写可读且易于理解的代码。以下是我发现的问题的非详尽清单。

设计问题

  • while(!feof(file)) is always wrong
  • 使用变量范围。如果您将sLsR的声明拉入循环,则无需重置它们。代码减少,潜在错误减少。
  • 您正在使用大量代码,就像将大概8位char转换为十六进制表示一样简单。实际上,您在代码中使用std::stringstream的唯一原因就是完全相同。为什么不将此功能与功能隔离?

不相关的问题

  • 由于代码格式不佳,您可能没有注意到使用sLsR时的复制粘贴错误:

    sL[0] = '\0';
    sR[0] = '\0';
    sL[1] = '\0';
    sL[1] = '\0';
    

    显然,最后一行应该是sR[1] = '\0';

样式问题

您的代码中有许多很多错误,但有一件容易阻止人们帮助的事情就是格式化。特别是空间格式化使您的代码非常难以阅读,因此我冒昧地编辑您问题中的“完整”代码以获得(几乎)一致的格式。一些基本问题变得明显:

  • 为变量和函数使用有意义的名称。我不知道你在这里要做什么,这无助于找到代码中的真正问题。
  • 混合<iostream><stdio.h>无助于您的代码的可读性。选择其中一个。事实上,only ever use <iostream> in C++
  • 除此之外,请使用适当的C ++标头名称(<cstring><cwchar>代替<string.h><wchar.h>)。
  • 复合语句后不要写分号。而不是

    int main(void) {
        if (condition) {
            one_statement();
            another_statement();
        };
    };
    

    你应该写

    int main(void) {
        if (condition) {
            one_statement();
            another_statement();
        }
    }
    

    ;单独声明的一部分。它还会阻止您使用else构造。

  • 在适当的地方使用初始化程序。所以不要写

    char ll[9];
    char rr[9];
    
    memset(ll, 0, 9);
    memset(rr, 0, 9);
    

    ,而

    char ll[9] = { 0 };
    char rr[9] = { 0 };
    

    更具可读性。

答案 1 :(得分:0)

This 0c problem can be solved by :

changing char[] array where the value is stored to unsigned char[];

when the input is read with string stream this line is very helpfull

<< std::setfill('0') << std::setw(2) <<std::hex ;

When 0c is converted to c setw(); sets the width of a stream and setfill() pads it with 0's.