-6

I have a work to do which I need to make a linux2dos function.

Basically I have to find all line feeds (0X0A) and put carriage return before it (0X0D).

As LFs and CRs are hidden in the file I don't really know how to work with them.

I think fgetc doesn't make the job, right?

Thanks!

  • 5
    Open the file in binary mode and they won't be hidden. – Barmar Nov 18 '19 at 21:34
  • 2
    Personally I find that using `0x` instead of `0X` for the hexideicmal prefix is easier to spot in code. And judging from the vast predominance of that form on-line I suspect that others do as well. – dmckee --- ex-moderator kitten Nov 18 '19 at 21:35
  • 1
    Secondly, in what sense do you think that non-printables are "hidden" in a file? The `FILE*` interface presents files as a bag-of-bytes. Some of those bytes may have the values you are looking for, – dmckee --- ex-moderator kitten Nov 18 '19 at 21:37
  • Doesn't Linux use `'\n'` (`0x0A`) and Dos uses `"\r\n"` (`0x0D0A`)? – Fiddling Bits Nov 18 '19 at 21:39
  • I don't know the answer for dos-derived OSes, but classic macos used `\r`, and then had the low-level read utilities translate on the fly *if you were in `TEXT` mode*. Opening in binary mode bypassed the massaging. – dmckee --- ex-moderator kitten Nov 18 '19 at 21:43
  • 1
    For text files on Windows systems (there may be other places where there's an issue, but there aren't many others these days), the CRLF notation on disk is converted to just LF (NL) as the file is read, and the converse applies as the file is written. Thus, using text files, you don't need to be aware of the line ending. On Unix-like systems, there is no 'text vs binary' distinction — and only NL (newline, `\n`) is used to separate lines. Some programs recognize CRLF sequences and treat them as if it was LF only, but most just treat the CR as another control character. – Jonathan Leffler Nov 18 '19 at 21:44
  • @FiddlingBits Exactly. That's what he's trying to do -- add the `\r` before `\n`. – Barmar Nov 18 '19 at 21:45
  • Note that quite a lot of internet protocols expect CRLF line endings, including http and https. Also note that the C standard recognizes `b` to denote 'binary mode' in calls to `fopen()` — which is ignored on Unix (all files are binary) but is relevant to Windows. – Jonathan Leffler Nov 18 '19 at 21:45
  • @Barmar I see now. I misread. – Fiddling Bits Nov 18 '19 at 21:45
  • @dmckee If you open the file in text mode on Windows, the `\r` characters will indeed be hidden, as it maps `\r\n` to `\n`. – Barmar Nov 18 '19 at 21:47

1 Answers1

0

Are you reading the data from a text file? is this on an embedded platform? If you are reading from a text file where all the data is ASCII, then you can get read a few bytes at a time and check for the newline '\n' (0X0A).

void FindAndUpdate(void)
{
    unsigned char buffer[256];
    unsigned char  newBuffer[sizeof(buffer)+1];
    unsigned char  *pChr;//pointer to where the \n is
    unsigned short location = 0, bytesRead, bytesWrote;
    FIL file, newFile;

    f_open(&newFile, "new.txt", FA_WRITE | FA_OPEN_APPEND );
    f_open(&newFile,  "old.txt",FA_READ);

    do{
        f_read(&file, buffer, sizeof(buffer), &bytesRead);
        pChr = strchr(buffer, '\n');
        if (NULL != pChr)
        {
            location = (pChar - &buffer[0])  - 1;
            //get where the \n is and minus 1 to get the index before it

            memcpy(newBuffer, buffer, location); //copy bytes to spot before \n
            newBuffer[location] = 0X0D; // insert '\r'
            memcpy(&newBuffer[location +1], pChr, bytesRead - location); //copy the rest of the array   
           f_write(&newFile, newBuffer, sizeof(newBuffer), &bytesWrote);
        }
    }while(bytesRead != 0);
    f_close(&file); //close file
    f_close(&newFile);//close file
    f_unlink(new.txt);//delete old file
    f_rename("old.txt", "new.txt");//rename file back to the origina name
}
o_tech
  • 15
  • 1
  • 9
  • How does `FileRead(buffer, sizeof(buffer), bytesRead);` set the value of `bytesRead`? – chux - Reinstate Monica Nov 19 '19 at 01:19
  • FileRead(buffer, sizeof(buffer), bytesRead); is pseudocode. i was just trying to show an example how you can read from a file. you didn't indicate the platform you are using. for example I am using f_read(&MyFile, buffer, sizeof(buffer),&bytesRead); to read from an SD card with stm32 – o_tech Nov 19 '19 at 03:05
  • bytesRead should be pass in by reference – o_tech Nov 19 '19 at 03:23