C convert string to boolean array

I need to convert a string consisting of milion characters 'zero' or 'one' (1039680 characters for a specific one) to a boolean array. Now I have a few seconds for a 300,000 character string and it is too long. I need to be able to complete the conversion of just a million characters in less than a second.

The way I tried to do this was to read a file with one line (in this test case) 300,000 zeros.

I know that my code will function for strings containing things other than zeros or ones, but I know that the string will only contain those.

I also looked at atoi, but I don't think this will suit my needs.

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

#define BUFFERSIZE 1039680

int main ()
{
    int i ;
    char buffer[BUFFERSIZE];
    bool boolList[BUFFERSIZE] ;

    // READ FILE WITH A LOT OF ZEROS
    FILE *fptr;
    if ((fptr=fopen("300000zeros.txt","r"))==NULL){
        printf("Error! opening file\n");
        exit(1);
    }
    fscanf(fptr,"%[^\n]",buffer);
    fclose(fptr);

    // CONVERT STRING TO BOOLEAN ARRAY
    for (i=0 ; i<strlen(buffer) ; i++) {
        if (buffer[i] == '1') boolList[i] = 1 ;
    }

    return 0;
}

      

+3


source to share


2 answers


Try



char *sptr = buffer;
bool *bptr = boolList;
while (*sptr != '\0')
    *bptr++ = *sptr++ == '1'? 1:0;

      

+4


source


If the string length is always 1039680 characters as you said, then why are you using strlen(buffer)

in your code? Why not just loop through BUFFERSIZE

once? And you should cache the result as others have said, instead of calling it over and over every loop.

Moreover, you have not included the space for the NULL terminated byte in the buffer, so when you read exact characters BUFFERSIZE

, the char array is not a valid null terminated string, so calling strlen on it causes undefined behavior

If you want to read the file as text, add another char to the buffer

char buffer[BUFFERSIZE + 1];

      

Otherwise, open the file as a binary and read the entire 1,039,680 byte block at once. It will be much faster



fread(buffer, sizeof(buffer[0]), BUFFERSIZE, fptr);

      

And then just flip the BUFFERSIZE

bytes and set it to 0 with no branch

for (i = 0 ; i < BUFFERSIZE; i++)
{
    buffer[i] -= '0';
}

      

You don't need another one boolList

, just use buffer

like boolList

or change the name to boolList

and drop the buffer

+2


source







All Articles