int CString::find() ignores newline character?

I have a text file that is of this format:

abc
def
ghi

I read this file into a character array and then passed it into a CString. When i did a find on the CString ( CString.find("def") ), instead of returning me value of 4, I get a value of 3. When i did CString.find("ghi"), i get 6 instead of 8. That made me believe CString::find() ignores newline chars when counting for the index. Is this true If it is, is there anyway I can make it include the newline chars in the count Would appreciate any insight on this. Thanks in advance!



Answer this question

int CString::find() ignores newline character?

  • Rajesh Ramaswami -MSFT

    I would turn your attentiion to how you're reading in the lines from the file.  Although it looks like you're using MFC, many library routines, such as Standard C++ library's istream::>> operator and the getline(istream,string&) function, use newlines and/or whitespace as text delimiters when reading from a file, and do not include those characters in their result strings.


  • Frank Babz

    Use your debugger and the memory window to see the contents.

  • Dr. Mojo

    ifstream iFile;
    CString Arr;
    int CurPos; //current position
    char* szTemp = new char[length];

    iFile.open(filename);
    iFile.read(szTemp, length);
    Arr = szTemp;
    CurPos = Arr.Find("def");

    Along this context.

  • Johan Koster

    Used the following file:
    abc
    def
    ghi

    The code is:

    ifstream iFile;
    iFile.open("abc.txt");
    CString strText;
    iFile.read(strText.GetBuffer(100), 100);
    int iCurPos = strText.Find("def");
    cout << "Position is " << iCurPos;

    The result is 4! As expected!



  • M Kuhn

    Thanks alot ppl, yup you guys are right, CString::find() works properly, after more debugging and viewing of memory locations i realised my problem came from ifstream::seekg(). I'm gonna start another thread on that issue, hope you guys will take a look. Thanks again ^^.

    Link to my new thread:
    PostID=108493#108493http://forums.microsoft.com/msdn/ShowPost.aspx PostID=108493#108493

  • SdwOne

    And as you see in my sample it works!

  • Catherine L D

    I know it works when you directly plug in the newline char using "\n". Try reading the line from a file into a char array, then pass it into a CString and try again. It won't return the correct value :( and i don't know why.
  • interface mirror

    With some minor changes I tested your code on an ascii test file that reads in exactly (according to the debugger) the string "abc\ndef\nghi\0". 

    Note that I had to change your code to Arr.Find(_T("def")). (This is why you should be posting exact code, because my changes might be masking your problem.)

    Arr.Find(_T("def")) is expected to return 4, and it does return 4.  (For both Unicode and non-Unicode builds).

    Arr.Find(_T("ghi")) is expected to return 8, and it does return 8.

    I'm wondering if this is an issue pertaining to ascii vs. wide-char (Unicode).

    Could you use your debugger to:
    1. see exactly what is in Arr.m_pszData (is it the same as the contents of szTemp, but in wchar_t*)
    2. Step into CStringT::Find() to see the steps taken to compute the result.  Note: you'll see the subtraction of two wchar_t pointers (in Unicode build), one being the result of wcsstr() and the other the start of the string, and subtraction gives the difference in characters not bytes.

    By the way, I'm using MFC 8.0 (VS 2005 Beta 2), and the Find() is implemented in atlmfc\include\cstring.h. 

    If you still have problems, please reply with your exact code (simplifying it down as much as possible in such a way it still manifests the problem, the version of MFC you are using, and whether you're building this code using Unicode.  Sorry to sound so strict, but you have a hard-to-reproduce issue.

    Thanks,
    Brian

    My code, inside a newly generated Unicode MFC project.

    #include <fstream>
    #include <sys/stat.h>

    // somefunction() {
    const
    char filename[] = "c:\\data.txt"; // created by typing text from first post in notepad

    struct _stat st;
    _stat( filename, &st );

    ifstream iFile;
    CString Arr;
    int CurPos; //current position
    char* szTemp = new char[st.st_size+1];

    iFile.open("c:\\data.txt");
    iFile.read(szTemp, st.st_size);
    szTemp[iFile.gcount()] =
    '\0';
    Arr = szTemp;
    CurPos = Arr.Find(_T(
    "ghi"));

    }


  • Scott Johnston

    No! This is not true.
    The following code works well:
    ASSERT(CString(_T("abc\ndef\nghi")).Find(_T("def"))==4);

  • Dmitry Makhno

    I am using an ifstream and performing ifstream::read to get the data from the file into a character array before passing it into a CString. I believe that newline chars were not discarded but if thats the case I don't know how to explain for the error in the return value I am seeing.
  • anurag chauhan

    I used the debugger and checked the memory location that is supposed to contain newline and found the ASCII 10 (which is newline). So this means there was no problem in reading in the contents of the file. So it brings me back to square 1 as to why CString::find() is returning index numbers as though it is skipping the newline chars :(
  • jankoesp

    No! It works! Just tried it.

    CStdioFile f(pszFileName,CFile::modeRead|CFile::typeText);
    i
    nt nLength= static_cast<int>(f.GetLength());
    PTSTR pszBuf= strData.GetBuffer(nLength);
    f.Read(pszBuf,nLength);
    pszBuf[nLength] = 0;
    strData.ReleaseBuffer();
    ASSERT(strData.Find("abc")==4);

    Whats your code to read the data



  • int CString::find() ignores newline character?