I've the following C function in a Windows API project that reads a file and based on the line endings (UNIX, MAC, DOS) it replaces the line endings with the right line-endings for Windows (\r\n):
// Standard C header needed for string functions #include <string.h> // Defines for line-ending conversion function #define LESTATUS INT #define LE_NO_CHANGES_NEEDED (0) #define LE_CHANGES_SUCCEEDED (1) #define LE_CHANGES_FAILED (-1) /// <summary> /// If the line endings in a block of data loaded from a file contain UNIX (\n) or MAC (\r) line endings, this function replaces it with DOS (\r\n) endings. /// </summary> /// <param name="inData">An array of bytes of input data.</param> /// <param name="inLen">The size, in bytes, of inData.</param> /// <param name="outData">An array of bytes to be populated with output data. This array must already be allocated</param> /// <param name="outLen">The maximum number of bytes that can be stored in outData.</param> /// <param name="bytesWritten">A pointer to an integer that receives the number of bytes written into outData.</param> /// <returns> /// If no changes were necessary (the file already contains \r\n line endings), then the return value is LE_NO_CHANGES_NEEDED.<br/> /// If changes were necessary, and it was possible to store the entire output buffer, the return value is LE_CHANGES_SUCCEEDED.<br/> /// If changes were necessary but the output buffer was too small, the return value is LE_CHANGES_FAILED.<br/> /// </returns> LESTATUS ConvertLineEndings(BYTE* inData, INT inLen, BYTE* outData, INT outLen, INT* bytesWritten) { char *posR = strstr(inData, "\r"); char *posN = strstr(inData, "\n"); // Case 1: the file already contains DOS/Windows line endings. // So, copy the input array into the output array as-is (if we can) // Report an error if the output array is too small to hold the input array; report success otherwise. if (posN != NULL && posR != NULL) { if (outLen >= inLen) { strcpy(outData, inData); return LE_NO_CHANGES_NEEDED; } return LE_CHANGES_FAILED; } // Case 2: the file contains UNIX line endings. else if (posN != NULL && posR == NULL) { int i = 0; int track = 0; for (i = 0; i < inLen; i++) { if (inData[i] != '\n') { outData[track] = inData[i]; track++; if (track>outLen) return LE_CHANGES_FAILED; } else { outData[track] = '\r'; track++; if (track > outLen) return LE_CHANGES_FAILED; outData[track] = '\n'; track++; if (track > outLen) return LE_CHANGES_FAILED; } *bytesWritten = track; } } // Case 3: the file contains Mac-style line endings. else if (posN == NULL && posR != NULL) { int i = 0; int track = 0; for (i = 0; i < inLen; i++) { if (inData[i] != '\r') { outData[track] = inData[i]; track++; if (track>outLen) return LE_CHANGES_FAILED; } else { outData[track] = '\r'; track++; if (track > outLen) return LE_CHANGES_FAILED; outData[track] = '\n'; track++; if (track > outLen) return LE_CHANGES_FAILED; } *bytesWritten = track; } } return LE_CHANGES_SUCCEEDED; } However, I feel like this function is very long (almost 70 lines) and could be reduced somehow. I've searched on Google but couldn't find anything useful; is there any function in either the C library or the Windows API that will allow me to perform a string-replace rather than manually searching the string byte-by-byte in O(n) time?