-1

WHAT THE CODE DOES: I read a binary file and sort it. I use a frequency array in order to do so. UPDATES:it does do the loop, but it doesn`t write the numbers correctly...

That is the code. I want to write on file after reading from it. I will suprascript what is already written, and that is okey. The problem is I have no error on compiling, but at run time it seems I have an infinite loop. The file is binary. I read it byte by byte and that`s also the way I want to write it.

while(fread(readChar, sizeof(readChar)/2, 1, inFile)){
    bit = atoi(readChar);
    array[bit] = array[bit] + 1;
}

fseek(inFile, 0, SEEK_SET);

for( i = 0; i < 256; i++) 
    while(array[i] > 0){
        writeChar[0] = array[i]; //do I correctly convert int to char?
        fwite(writeChar, sizeof(readChar)/2, 1, inFile);
        array[i] = array[i] -1;
    }

The inFile file declaration is:

FILE* inFile = fopen (readFile, "rb+");

It reads from the file, but does not write!

Lulu
  • 175
  • 1
  • 2
  • 12
  • Check the return value from `fread()` for errors. – Mark Setchell Jan 15 '15 at 09:27
  • isn't `while (fread()..` lacking the closing parenthesis? – Sourav Ghosh Jan 15 '15 at 09:32
  • 1
    Is the readChar variable by any chance one byte long? Because if yes that could create a loop, since you would infinitely read 1 times zero characters. – Pyjong Jan 15 '15 at 09:35
  • 2
    It's not like I don't believe you, but could you provide the declaration of this variable? – Pyjong Jan 15 '15 at 09:44
  • I also note that you have an unmatched parenthesis. The last line of your snippet has a `}`, yet there isn't a `{` to go with it. Perhaps it should be on the line that follows `while(array[i]>0)`? If so, you really should explicitly enclose the contents of the for loop too. The `fwrite` call will only ever be executed once, since the for loop runs the `while (array[i] > 0)` statement 256 times, and that while construct only sets `writechar[0]` to `writechar[i]`. After this while loop contained in the for loop has finished, `frwite` will be called once, as will be `array[i] = array[i]-1;` – enhzflep Jan 15 '15 at 10:10
  • `while(array[i] > 0)` --> `while(array[i] > 0){` ?? – BLUEPIXY Jan 15 '15 at 10:12
  • Sorry, I have edited it. it gets into for and only stays at i=0...creating infinite loop – Lulu Jan 15 '15 at 10:26
  • Your comment in the code says it doesn't get into the for loop? – Mark Setchell Jan 15 '15 at 10:30
  • How about using a debugger? – Mark Setchell Jan 15 '15 at 10:31
  • How about posting something that reproduces the problem? – Karoly Horvath Jan 15 '15 at 10:33
  • writeChar[0] = array[i]; //do I correctly convert int to char? fwrite(writeChar, sizeof(readChar)/2, 1, inFile); I think the problem is here. I vant to convert int to char* because the first parameter of fwrite is char*....but my conversion in wrongly done – Lulu Jan 15 '15 at 10:39
  • 1
    You say you read a file bit by bit. You can't in C. The smallest unit is a byte. The statement `bit = atoi(readChar);` does not what you think it does. Please provide a *complete* compilabale example. – Jens Jan 15 '15 at 11:00
  • Both the inner while loop and the outer for loop will terminate (as the code is curently shown). Hence there is no problem, unless here is some side efect from code or declarations not shown. Please provide a complete example that can be compiled and shows the problematic behavior. – Paul Ogilvie Jan 15 '15 at 13:05

2 Answers2

0

The only possible reason for an infinite loop I see is, that your array is not initialized.
After declaration with:

int array[256];

the elements can have any integer value, also very large ones.
So there are no infinite loops, but some loops can have very much iterations.
You should initialize your array with zeros:

int array[256]={0};

I don't know the count of elements in your array and if this is the way you declare it, but if you declare your array like shown, than ={0} will initialize all members with 0. You also can use a loop:

for(int i=0; i < COUNT_OF_ELEMENTS;i++) array[i] = 0;

EDIT: I forgot to mention, that your code is only able to sort files with only numbers within.
For that, you have also to change the conversion while writing:

char writeChar[2]={0};
for( int i = 0; i < 256; i++) 
    while(array[i] > 0){
        _itoa(i,writeChar,10);
        fwrite(writeChar, sizeof(char), 1, inFile);
        array[i] = array[i] -1;
    }   

File content before:
12345735280735612385478504873457835489

File content after:
00112223333334444455555556777778888889

Is that what you want?

Gren
  • 1,850
  • 1
  • 11
  • 16
0

Undefined behavior:

fread() is used to read a binary representation of data. atoi() takes a textual represetation of data: a string (a pointer to an array of char that is terminated with a '\0'.

Unless the data read into readChar has one of its bytes set to 0, calling atoi() may access data outside readChar.

fread(readChar, sizeof(readChar)/2, 1, inFile);
bit = atoi(readChar);

Code it not reading data "bit by bit" At @Jens comments: "The smallest unit is a byte." and that is at least 8 bits.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256