Thread: Problem with the control characters

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    99

    Problem with the control characters

    dear all,

    one strange behaviour i have seen in my program that the program works fine for the control characters means it reads the files properly,but when i remove the control characters from my file some data get lost from that file while reading what can be reason,
    any suggestions please.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    I'd guess it still means there are bugs in your code.

    Did you switch from reading in binary mode to reading in text mode?

    Post your code, not a description.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2007
    Posts
    99

    problem with control characters

    dear experts thank you for the reply,

    here is the piece of code that i am trying to do

    Code:
    fpFile = fopen(filename,"rb");//here filename is "test.csv"
    if (fpFile != NULL)
    {
    char buf[SizeValue];//here SizeValue is the size of the file for that i am using separat function to find out .
    fread(buf, 1, SizeValue , fpFile);
    strcat(buf,"\0");
    
    getMstringVector(buf, '\n', *svect);//which converts from buffer to a vector svect
    int scount = svect->getCount();//which gives nummber of lines 
    for(int i = 0; i < scount-1; ++i)
      {
    if((*svect)[i].indexOf('\r')) //which checks for control characters
    { 
    (*svect)[i].replace('\r','\0');
    	
    }
       getMstringVector((*svect)[i], ",", *tvect);//which converts each line based on delimeters(,) to a vector tvect
    
    int tcount = tvect->getCount();
    if( tcount > 0)
    {
      for(int j = 0; j < tcount; ++j)
        {
         char *tvect1;
         tvect1 = (char*)(*tvect)[j];
         char *str2 = strtok(tvect1, search_str);
           while(str2)
           {
    		   
            int length = strlen(str2);
            char *mystr = 0;
             mystr = new Mbyte[length];
            strcpy(mystr, str2);
           str2 = strtok(NULL, search_str);
            like this the code follows this is the main snippet
    }
    }
    }
    }

    so this works fine with the file with control characters but not for the file without control characters
    please some suggestion.

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It looks like you don't allocate enough memory for the null-terminator in your strings. You need strlen(x) + 1 bytes to store the string x.

    As it is C++, you might also be better off using strings and vectors.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    Registered User
    Join Date
    Nov 2007
    Posts
    99
    Dear experts,
    please tell me is there any way to split the given string based on delimeters apart from using strtok() function, please tell me because i think there is a problem with that only.

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    One way would be to use boost's string algorithms library:

    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    #include <boost/algorithm/string.hpp>
    
    int main()
    {
        std::string s("first,second,third\nfourth,and last");
        std::cout << s << "\n\n";
        std::vector<std::string> vec;
        boost::split(vec, s, boost::is_any_of(",\n"));
        for (unsigned i = 0; i != vec.size(); ++i) {
            std::cout << "'" << vec[i] << "'" << '\n';
        }
    }
    Another way might be to read the file with getline and then use a stringstream and another form of getline to split each line at commas.

    If you have a file of comma-separated values, then I don't see why you should read it in binary mode and why you should be so much worried about control characters. On the other hand, there are escape sequences (quoted strings?) which means that simply splitting the file contents at commas and newlines won't necessarily produce the correct results.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    strcat(buf,"\0");
    is absolutely pointless - it will insert a zero at the end of the string, which is already indicated by a zero. If there is no zero at the end of the string in the first place, strcat will go beyond the end of the actual string variable, and the zero will be put in the place where the first zero appears in memory (unless it crashes first).

    Generally, fread is not great for reading text files, and it doesn't put a zero on the end of the buffer. fgets reads a line, which is great for text files.

    A .csv file is a text file, so there is no need to open it as a binary file, nor does it make any sense to replace '\r' with '\0' in that case, since all '\r' would be removed at that point.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Nov 2007
    Posts
    99

    small doubt

    dear all,
    i have one small question elated to this,

    how to print the std::string into the fprintf(),
    Code:
    for eg:
    std::string line;//which contains some data
    fprintf(fpfile,"%s",line)
    which is giving me a junk value what is the proper way of using this, means i am taking the value of line into the file which is opened for write mode.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    That would of course not work, the C function fprintf() has no idea what a C++ std::string is.

    You could fix the problem by passing the constant C string, e.g. fprintf(fpfile, "%s", line.c_str()); .

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Quote Originally Posted by vin_pll View Post
    dear all,
    i have one small question elated to this,

    how to print the std::string into the fprintf(),
    Code:
    for eg:
    std::string line;//which contains some data
    fprintf(fpfile,"%s",line)
    which is giving me a junk value what is the proper way of using this, means i am taking the value of line into the file which is opened for write mode.
    You can use line.c_str() which return a char* so you can use a std::string in C string fucntions

  11. #11
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Another simple string splitting function that I like to use is as follows:

    Code:
    void StringSplit(const std::string& str, char delim, std::vector<std::string>& v)
    {
      std::string token;
      std::stringstream ss;
      ss.str(str);
      while (getline(ss, token, delim))
      {
        v.push_back(token);
      }
    }

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Elkvis
    Another simple string splitting function that I like to use is as follows:
    That is pretty much what anon described as a specific alternative to boost::split, but incidentally,
    Code:
    std::stringstream ss;
    ss.str(str);
    can be simplified to:
    Code:
    std::stringstream ss(str);
    and since you are fully qualifying all names in the std namespace, it makes sense to qualify getline() as std::getline() as well.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by laserlight View Post
    and since you are fully qualifying all names in the std namespace, it makes sense to qualify getline() as std::getline() as well.
    good point. can't believe I missed that. it's interesting to note that with no 'using' statements in my program, getline works with no std:: specifier in front. I'm not exactly sure what to think of that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with hw problem: counting characters in a string
    By pinkfloyd4ever in forum C++ Programming
    Replies: 11
    Last Post: 11-04-2007, 11:18 PM
  2. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  3. Control characters to emulate a prompt?
    By xconspirisist in forum Windows Programming
    Replies: 3
    Last Post: 02-08-2006, 04:16 PM
  4. Problem Calling Destructor, and prob with cin.
    By imortal in forum C++ Programming
    Replies: 2
    Last Post: 10-10-2003, 09:29 AM
  5. Edit Control problem
    By Malek in forum Windows Programming
    Replies: 3
    Last Post: 06-16-2002, 01:12 AM