Thread: Problems with c-style strings

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    7

    Problems with c-style strings

    Hey guys, hope some of you will help with this problem i have.
    Code:
    #ifndef ELEM_H
    #define ELEM_H
    
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    const int size=30;
    
    class elem
    {
    public:
           elem();
           void setkey(int);
           int getkey();
           void setnext(int);
           int getnext();
           void setprev(int);
           int getprev();
           void setinfo(char *);
           void add(fstream &);       
    private:
            int key;
            int next;
            int prev;
            char info[size];
    };
    
    elem::elem()
    {
          key=next=prev=0;
    	  for(int i=0;i<30;i++)
    	  {
    		  info[i]=' ';
    	  }
    
    }
             
    void elem::setkey(int k)
    {
         key=k;
    }
    
    int elem::getkey()
    {
        return key;
    }
    
    void elem::setnext(int nex)
    {
         next=nex;
    }
    
    int elem::getnext()
    {
        return next;
    }
    
    void elem::setprev(int pre)
    {
         prev=pre;
    }
    
    int elem::getprev()
    {
        return prev;
    }
    
    void elem::setinfo(char * inf)
    {
        for (int i=0;i<30;i++)
    	{
    		info[i]=inf[i];
    	}
    }
    
    void elem::add(fstream &fout)
    {
         fout.seekp(0,ios::end);
         fout.write((char*)&key,sizeof(int));
         fout.write(info,size);
         fout.write((char*)&prev,sizeof(int));
         fout.write((char*)&next,sizeof(int));
         fout.clear();
    }
    
    #endif
    this is header

    Code:
    #include <iostream>
    #include <fstream>
    #include <cmath>
    #include "elem.h"
    #include <string>
    
    using namespace std;                                                            
    
    bool menu(int &);                                                               //menu lietotajam
    int findPosNext(fstream &,int);                                                 //atrodam nakamo atslegu
    int findPosPrev(fstream &,int);                                                 //atrodam iepriekseo atslegu
    void initPoint(fstream &);                                                      //uzstadam nakamo uz ieprieksejo atslegu
    void print(fstream &);                                                          //izdruka 
    void printBack(fstream &);                                                      //izdruka 
    
    
    int main()
    {
        int ok=1,num=0,choice=1;
        char inff[30];
        string filen;
    
    do{
    cout<<"Enter the name of the file with an extension (.bin)\n";
    cin>>filen;
     fstream f;
    
     f.open(filen.c_str(),ios::out|ios::in|ios::binary);
                                                                                    //lietotais ievada faila nosaukumu
    while(menu(choice))                                                             //izveidojam pec tam atveram failu
    {                                                                               //kamer lietotais neievada -100
     switch(choice)
     {
           case 1:                                                                  //izveido objektu
                {elem obj1;                                                         //ieraksta atslegu un saturu
                cout<<"\nEnter the Key of record\n";
                cin>>num;
                obj1.setkey(num);
                cout<<"Enter the value of record\n";
                cin.getline(inff,30,'/0');
                obj1.setinfo(inff);
    			obj1.add(f);                                                        //pievieno componentu failam
    			initPoint(f);}                                                      //uzstada next un prev
    			break;
    		case 2:
    			{print(f);}                                                         //izdruka
    			break;
    		case 3:
    			{printBack(f);}                                                     //izdruka
    			break;
    }
    }			
    f.close();
    cout<<"Procceed with new file? (1)  or exit (0) \n";                            //atkartosanas iespeja
    cin>>ok;
    }
    while(ok!=0);
    return 0;
    }            
                
    bool menu(int &choice)                                                          //lietotaja izvele
    {
        cout<<"\nEnter your choice\n"
        <<"1 - to add a record to file\n"
        <<"2 - to print\n"
        <<"3 - to print backwards\n"
        <<"-100 to end this file proccessing\n";
        cin>>choice;
        return choice!=-100;
    }
    
    int findPosNext(fstream &f,int key)                                             //ejam caur failu
    {                                                                               //meklejam vismazako starpibu starp divam key
        int next=0,cur,gap=32000;                                                   //un lai key butu mazak
    	
    	f.seekg(0,ios::beg);
        
        while(f)
        {
                f.read((char*)&cur,sizeof(int));
                if(fabs((double)cur-(double)key)<gap&&key<cur)
                {
    					next=cur;
    					gap=fabs((double)cur-(double)key);
    			}        
                f.seekg(38,ios::cur);
    	}
    	f.clear();
    	return next;                                                                //atgriezam next atslegu
    }
    	
    int findPosPrev(fstream &f,int key)                                             //tas pats bet meklejam mazako starpibu
    {                                                                               //un lai key butu mazak
        int prev=0,cur,gap=32000;
        
    	f.seekg(0,ios::beg);
    	
        while(f)
        {
                f.read((char*)&cur,sizeof(int));
                if(fabs((double)cur-(double)key)<gap&&key>cur)
                {
    					prev=cur;
    					gap=fabs((double)cur-(double)key);
    			}        
                f.seekg(38,ios::cur);
    	}
    	f.clear();
    	return prev;
    }
    
    void initPoint(fstream &f)                                                      //ejam caur failu
    {                                                                               //atrodam katram key , nakamo atslegu
    	int key=0,prev=0,next=0,pos=0;                                              //uzstadam to, katrai komponentei
    	
    	f.seekg(0,ios::beg);
    	f.read((char*)&key,sizeof(int));
    	
    	while(f)
    	{
    		pos=f.tellg();
    		prev=findPosPrev(f,key);
    		next=findPosNext(f,key);
    		f.seekp(pos+30,ios::beg);
    		f.write((char*)&prev,sizeof(int));
    		f.write((char*)&next,sizeof(int));
    		f.seekg(pos+38,ios::beg);
    		f.read((char*)&key,sizeof(int));
    		
    	}
    f.clear();
    }
    
    void print(fstream &f)                                                          //ejam caur failu , atrodam mazako key
    {                                                                               //drukam to , skatamies uz next
    	int key=0,next=1,pos=0,small=32000;                                         //ejam caur failu , atrodam next , drukam to
        char inff[size];
        
        f.seekg(0,ios::beg);
    	while(f)
    	{
    		f.read((char*)&key,sizeof(int));
    		if(key<small) 
    		{
    			small=key;
    			pos=f.tellg();
    		}
    		f.seekg(38,ios::cur);
    	}
    	f.clear();
    	key=small;
    	
    	while(next!=0)
    	{
    		f.seekg(pos,ios::beg);
    		cout<<key<<" ";
    		f.read(inff,size);
    		cout<<inff<<endl;
    		f.seekg(4,ios::cur);
    		f.read((char*)&next,sizeof(int));
    		if(next!=0)
    		{
                       f.seekg(0,ios::beg);
                       
                       while(f)
                       {
    					f.read((char*)&key,sizeof(int));
    					if(key==next)
    					{
    						pos=f.tellg();
    						break;
    					}
    					f.seekg(38,ios::cur);
    					}
    					f.clear();
    				
    	}
    }
    f.clear();
    }	
    void printBack(fstream &f)                                                      //viss tas pats bet sakuma atrodam lielako key
    {                                                                               //un pec meklejam prev
    	int key=0,next=1,pos=0,small=0;
        char inff[size];
        
        f.seekg(0,ios::beg);
    	while(f)
    	{
    		f.read((char*)&key,sizeof(int));
    		if(key>small) 
    		{
    			small=key;
    			pos=f.tellg();
    		}
    		f.seekg(38,ios::cur);
    	}
    	f.clear();
    	
    	while(next!=0)
    	{
    		f.seekg(pos,ios::beg);
    		cout<<key<<" ";
    		f.read(inff,size);
    		cout<<inff<<endl;
    		f.read((char*)&next,sizeof(int));
    		if(next!=0)
    		{
                       f.seekg(0,ios::beg);
                       
                       while(f)
                       {
    					f.read((char*)&key,sizeof(int));
    					if(key==next)
    					{
    						pos=f.tellg();
    						break;
    					}
    					f.seekg(38,ios::cur);
    					}
    					f.clear();
    				
    	}
    }
    f.clear();
    }
    so basically , the problem is that, when i am reading input from user ( with cin>> , or cin.getline) the program takes the input and fills c-style string info with it( for example i input "asdasdasd", and program fills string with this information) , then it adds terminating symbol (/0) , and then , if there is some space unused, the program fills this space with ASCII representation of the byte 0xCC(found this at some website) , anyway , i don't know , how to get rid of it
    any ideas?
    p.s. when i am trying to output the content of string for example on the string , the program goes into infinite cycle and outputs this byte.

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    There are a couple of things wrong with the following code snippet:
    Code:
    cin.getline(inff,30,'/0');
    The '/0' is a multi-character constant the char '/' and the char '0' you probably meant '\0'. However you should probably be using '\n', newline character instead of the end of the end of string character '\0'.

    You also need to pick an indent style and use it consistently.


    Jim
    Last edited by jimblumberg; 05-21-2011 at 04:14 PM.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you are using C-style strings, then it is completely irrelevant what bytes come after the \0 character. \0 ends the string, end of story.

  4. #4
    Registered User
    Join Date
    May 2011
    Posts
    7
    so i checked with visual studio debugger
    when i am creating class elem object in main( elem obj1 )
    the data member info of object obj1 is filled with
    [0] -52 'Ģ' char
    this value for all array cells

    when i am reading input with cin , all free cells are filled with this value

    bump

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by possik View Post
    so i checked with visual studio debugger
    when i am creating class elem object in main( elem obj1 )
    the data member info of object obj1 is filled with
    [0] -52 'Ģ' char
    this value for all array cells

    when i am reading input with cin , all free cells are filled with this value

    bump
    That is entirely expected and normal and not anything to worry about.

    Well, sort of. You using C-strings in a C++ program is definitely something to worry about. But once you have made that choice, those char arrays have to be filled with some character, and -52 is as good as anything else. If you are having difficulties, you will need to be more specific about where in your program those appear, and why.

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Please replace tabs with a fixed number spaces before posting. Also correct your indentation and make sure the lines aren't too long, including removing the comments if necessary, or simply not tabbing them out so far.
    You aren't using the constant you declared consistently, and you don't have const-correctness.
    The 0xCC bytes are not the problem. The problem is a bug in your code.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    Registered User xentaka's Avatar
    Join Date
    May 2011
    Posts
    60
    Used auto formatter in codeblocks to help out :

    Code:
    #include <iostream>
    #include <fstream>
    #include <cmath>
    #include "elem.h"
    #include <string>
    
    using namespace std;
    
    bool menu(int &);                                                               //menu lietotajam
    int findPosNext(fstream &,int);                                                 //atrodam nakamo atslegu
    int findPosPrev(fstream &,int);                                                 //atrodam iepriekseo atslegu
    void initPoint(fstream &);                                                      //uzstadam nakamo uz ieprieksejo atslegu
    void print(fstream &);                                                          //izdruka
    void printBack(fstream &);                                                      //izdruka
    
    
    int main()
    {
        int ok=1,num=0,choice=1;
        char inff[30];
        string filen;
    
        do
        {
            cout<<"Enter the name of the file with an extension (.bin)\n";
            cin>>filen;
            fstream f;
    
            f.open(filen.c_str(),ios::out|ios::in|ios::binary);
            //lietotais ievada faila nosaukumu
            while(menu(choice))                                                             //izveidojam pec tam atveram failu
            {
                //kamer lietotais neievada -100
                switch(choice)
                {
                case 1:                                                                  //izveido objektu
                {
                    elem obj1;                                                         //ieraksta atslegu un saturu
                    cout<<"\nEnter the Key of record\n";
                    cin>>num;
                    obj1.setkey(num);
                    cout<<"Enter the value of record\n";
                    cin.getline(inff,30,'/0');
                    obj1.setinfo(inff);
                    obj1.add(f);                                                        //pievieno componentu failam
                    initPoint(f);
                }                                                      //uzstada next un prev
                break;
                case 2:
                {
                    print(f);    //izdruka
                }
                break;
                case 3:
                {
                    printBack(f);    //izdruka
                }
                break;
                }
            }
            f.close();
            cout<<"Procceed with new file? (1)  or exit (0) \n";                            //atkartosanas iespeja
            cin>>ok;
        }
        while(ok!=0);
        return 0;
    }
    
    bool menu(int &choice)                                                          //lietotaja izvele
    {
        cout<<"\nEnter your choice\n"
            <<"1 - to add a record to file\n"
            <<"2 - to print\n"
            <<"3 - to print backwards\n"
            <<"-100 to end this file proccessing\n";
        cin>>choice;
        return choice!=-100;
    }
    
    int findPosNext(fstream &f,int key)                                             //ejam caur failu
    {
        //meklejam vismazako starpibu starp divam key
        int next=0,cur,gap=32000;                                                   //un lai key butu mazak
    
        f.seekg(0,ios::beg);
    
        while(f)
        {
            f.read((char*)&cur,sizeof(int));
            if(fabs((double)cur-(double)key)<gap&&key<cur)
            {
                next=cur;
                gap=fabs((double)cur-(double)key);
            }
            f.seekg(38,ios::cur);
        }
        f.clear();
        return next;                                                                //atgriezam next atslegu
    }
    
    int findPosPrev(fstream &f,int key)                                             //tas pats bet meklejam mazako starpibu
    {
        //un lai key butu mazak
        int prev=0,cur,gap=32000;
    
        f.seekg(0,ios::beg);
    
        while(f)
        {
            f.read((char*)&cur,sizeof(int));
            if(fabs((double)cur-(double)key)<gap&&key>cur)
            {
                prev=cur;
                gap=fabs((double)cur-(double)key);
            }
            f.seekg(38,ios::cur);
        }
        f.clear();
        return prev;
    }
    
    void initPoint(fstream &f)                                                      //ejam caur failu
    {
        //atrodam katram key , nakamo atslegu
        int key=0,prev=0,next=0,pos=0;                                              //uzstadam to, katrai komponentei
    
        f.seekg(0,ios::beg);
        f.read((char*)&key,sizeof(int));
    
        while(f)
        {
            pos=f.tellg();
            prev=findPosPrev(f,key);
            next=findPosNext(f,key);
            f.seekp(pos+30,ios::beg);
            f.write((char*)&prev,sizeof(int));
            f.write((char*)&next,sizeof(int));
            f.seekg(pos+38,ios::beg);
            f.read((char*)&key,sizeof(int));
    
        }
        f.clear();
    }
    
    void print(fstream &f)                                                          //ejam caur failu , atrodam mazako key
    {
        //drukam to , skatamies uz next
        int key=0,next=1,pos=0,small=32000;                                         //ejam caur failu , atrodam next , drukam to
        char inff[size];
    
        f.seekg(0,ios::beg);
        while(f)
        {
            f.read((char*)&key,sizeof(int));
            if(key<small)
            {
                small=key;
                pos=f.tellg();
            }
            f.seekg(38,ios::cur);
        }
        f.clear();
        key=small;
    
        while(next!=0)
        {
            f.seekg(pos,ios::beg);
            cout<<key<<" ";
            f.read(inff,size);
            cout<<inff<<endl;
            f.seekg(4,ios::cur);
            f.read((char*)&next,sizeof(int));
            if(next!=0)
            {
                f.seekg(0,ios::beg);
    
                while(f)
                {
                    f.read((char*)&key,sizeof(int));
                    if(key==next)
                    {
                        pos=f.tellg();
                        break;
                    }
                    f.seekg(38,ios::cur);
                }
                f.clear();
    
            }
        }
        f.clear();
    }
    void printBack(fstream &f)                                                      //viss tas pats bet sakuma atrodam lielako key
    {
        //un pec meklejam prev
        int key=0,next=1,pos=0,small=0;
        char inff[size];
    
        f.seekg(0,ios::beg);
        while(f)
        {
            f.read((char*)&key,sizeof(int));
            if(key>small)
            {
                small=key;
                pos=f.tellg();
            }
            f.seekg(38,ios::cur);
        }
        f.clear();
    
        while(next!=0)
        {
            f.seekg(pos,ios::beg);
            cout<<key<<" ";
            f.read(inff,size);
            cout<<inff<<endl;
            f.read((char*)&next,sizeof(int));
            if(next!=0)
            {
                f.seekg(0,ios::beg);
    
                while(f)
                {
                    f.read((char*)&key,sizeof(int));
                    if(key==next)
                    {
                        pos=f.tellg();
                        break;
                    }
                    f.seekg(38,ios::cur);
                }
                f.clear();
    
            }
        }
        f.clear();
    }

  8. #8
    Registered User
    Join Date
    May 2011
    Posts
    7
    thx for sanitizing my code, bump

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I'm just going to say this:
    No one wants to look through a long, complex example of code to find your bug.
    You should post the smallest possible compilable example where this bug still occurs.
    While you're at it, fix the '/0' and the indentation.
    Then try again instead of posting useless bumping messages.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    May 2011
    Posts
    7
    ok , maybe this is the source of the bug
    in this function
    Code:
    void print(fstream &f)                                                          //ejam caur failu , atrodam mazako key
    {
        //drukam to , skatamies uz next
        int key=0,next=1,pos=0,small=32000;                                         //ejam caur failu , atrodam next , drukam to
        char inff[size];
    
        f.seekg(0,ios::beg);
    	pos=f.tellg();
        while(f)
        {
            f.read((char*)&key,sizeof(int));
            if(key<small)
            {
                small=key;
                pos=f.tellg();
            }
            f.seekg(38,ios::cur);
        }
        f.clear();
        key=small;
    
        while(next!=0)
        {
            f.seekg(pos,ios::beg);
            cout<<key<<" ";
            f.read(inff,size);
            cout<<inff<<endl;
            f.seekg(4,ios::cur);
            f.read((char*)&next,sizeof(int));
            if(next!=0)
            {
                f.seekg(0,ios::beg);
    
                while(f)
                {
                    f.read((char*)&key,sizeof(int));
                    if(key==next)
                    {
                        pos=f.tellg();
                        break;
                    }
                    f.seekg(38,ios::cur);
                }
                f.clear();
    
            }
        }
        f.clear();
    }
    and in the almost similar function ( printBack )

    the seekg() functions not working properly

    so in the beginning of function in lines:

    Code:
        char inff[size];
    
        f.seekg(0,ios::beg);
    	pos=f.tellg();
        while(f)
        {
    Code:
     f.seekg(0,ios::beg);
    puts the get pointer to the -1 position, and i cannot enter the while cycle.

    maybe this is the source of the bug ? (((

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    It's doubtful that seekg'ing to the beginning of the file could cause a problem (although I suppose you never know). You probably passed in a filestream that was in a bad state -- and no function works on a filestream that is in a bad state; you have to clear it first. So you should go back and see just when your filestream goes bad.

  12. #12
    Registered User
    Join Date
    May 2011
    Posts
    7
    ok , i checked the file stream.
    Code:
     fstream f;
    
            f.open(filen.c_str(),ios::out|ios::in|ios::binary);
    		num=f.fail();
    after these commands in main() function, the fail bit of the stream is set to 1.
    but i don't why?
    which types of error could it be?

    could it be the string converting to c-style string/?
    Last edited by possik; 05-23-2011 at 05:23 PM. Reason: a clue

  13. #13
    Registered User
    Join Date
    May 2011
    Posts
    7
    bump , still haven't found the solution to this problem ((

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Instead of useless bumps, follow the advice in post #9!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    One of my greatest annoyances with C++ is how indistinct it is with file I/O errors.
    Code:
    #include <cstdio>
    #include <errno.h>
    
    fstream f;
    f.open(filen.c_str(),ios::out|ios::in|ios::binary);
    if (f.is_open() == false)
    {
       std::perror( filen.c_str() );
    }
    I'm not positive this will help but does perror say anything is wrong?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Clarification with C-style Strings
    By StapleGun in forum C Programming
    Replies: 8
    Last Post: 10-30-2008, 07:46 PM
  2. Converting C++ Style strings...
    By LightsOut06 in forum C++ Programming
    Replies: 10
    Last Post: 10-26-2005, 03:02 PM
  3. More problems with C style strings
    By mousey in forum C++ Programming
    Replies: 3
    Last Post: 10-21-2003, 01:52 PM
  4. converting c style strings to c++ strings
    By fbplayr78 in forum C++ Programming
    Replies: 6
    Last Post: 04-14-2003, 03:13 AM
  5. c-style string vs. c++-style strings
    By Mbrio in forum C++ Programming
    Replies: 3
    Last Post: 02-10-2002, 12:26 PM