Thread: Need help about string

  1. #1
    Registered User
    Join Date
    Dec 2005
    Posts
    29

    Need help about string

    Hello,this is my code.

    here is the output.

    http://img201.imageshack.us/img201/5564/cppqt3.jpg

    the problem is,
    the output must look like this.

    ========================
    Group :

    Group :
    ========================

    this mean,user can insert 2 groups.

    example :

    ========================
    Group : Group A

    Group : Group B
    ========================

    and the program will save the group name as a file.

    Can some one fix this code ?




    Code:
    #include <iostream>
    #include <conio.h>
    #include <string>
    #include <fstream>
    
    using namespace std;
    
    int main ()
    {
        
        char groupname[300];
        int numGroups;
        
        cout<<"How many groups do you wish to create?"<<endl;
        cin>>numGroups;
        
        for(int i=0;i<numGroups;i++)
        {
                cout << "Group : ";
                cin.getline(groupname,30);
                
                ofstream group;
                ofstream (groupname, ios::out);
        }
      
      getch();
      return 0;
    }

  2. #2
    Registered User
    Join Date
    Dec 2006
    Posts
    30
    the first time you pressed return after the number, the "cin>>numGroups" only retrieves the number, and the newline stays in there

    so the next time you call cin.getline(groupname,30), it retrieves an empty line

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    A common solution is to add cin.ignore() immediately after the call to cin>>numGroups to ignore the <enter> typed by the user.

    Note that you #included <string> but you are not using the C++ string class. Unless you have a good reason, you should prefer C++ strings over the C style character arrays you are using.

  4. #4
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    OK,
    I already fix it.
    the code is working but i got a problem with the file output.

    let say the file name is like this :

    example :

    ========================
    Group : test1

    Group : test2
    ========================

    when i checked in the folder,2 files has been created.

    check this screenshot

    http://img187.imageshack.us/img187/1264/cpp2qn6.jpg


    1 file is === test1
    another file is == est2

    the problem is, why "G" is missing for Group B ?

    maybe anyone can fix my code or give me some idea.
    Last edited by vearns; 12-19-2006 at 01:47 AM.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    No idea, show us the code, not your output.
    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.

  6. #6
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    Code:
        char groupname[300];
        int numGroups;
        
        cout<<"How many groups do you wish to create?"<<endl;
        cin>>numGroups;
        
        for(int i=0;i<numGroups;i++)
        {
                cout << "Group Name : ";
                cin.ignore();
                cin.getline(groupname,30);
                
                ofstream group;
                ofstream (groupname, ios::out);
        }

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > cin.ignore();
    This is great at removing the trailing junk from cin>>numGroups; but on the 2nd iteration, it removes the first char of each line of input.

    Maybe do this once, before entering the loop?
    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.

  8. #8
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    HOho man...thats great....it is working now !

  9. #9
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    Code:
    using namespace std;
      
    string groupname;
    int numGroups;
    ofstream group;
        
    cout<<"How many groups do you wish to create?"<<endl;
    cin>>numGroups;
    cin.ignore();
        
    for(int i=0;i<numGroups;i++)
        {
                cout << "Group Name : ";
                if(getline(cin,groupname).gcount() > 30)
                    {
                       cout << "No more than 30 characters, please." << endl;
                       i--;
                       continue;
                    }
    
                group.open(groupname.c_str());
                group.close();
        }
    Last edited by CodeMonkey; 12-19-2006 at 06:55 PM.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> std::string groupname;
    Using a C++ string instead of C style strings is an improvement.

    >> cout << "No more than 30 characters, please." << endl;
    I don't think the check for 30 characters is necessary, though, as it was almost certainly only originally needed to avoid overstepping the character array bounds.

    >> if(std::getline(cin,groupname) > 30)
    This won't work, getline does not return the number of characters read. As I mentioned above, the > 30 is probably not necessary anyway, so if(std::getline(cin,groupname)) should be good.

    >> ofstream group;
    Moving a variable to a larger scope unnecessarily is not an improvement, IMO. There will be no noticeable performance benefits, and keeping the variable scope limited is better design here.

    >> group.close();
    You would also want to clear() any failbits at the end of the loop just in case, although this would be more likely to cause a problem on an input file. Of course, moving the variable declaration back inside the for loop scope would make the close() automatic and a clear() unnecessary.

    >> group.open(groupname);
    This should be group.open(groupname.c_str()); since filestreams take C style strings as arguments to open.

  11. #11
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    It seems you replied to my code as I was editing it. Anyway, all of your comments did apply.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  12. #12
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    Hello,
    why when i inserted group name without space,the program suddenly quit.

    here is my code

    Code:
    #include<iostream>
    #include<string>
    #include<fstream>
    #include<conio.h>
    
    using namespace std;
    
    int main()
    {
        cout<<"How many groups?"<<endl;
        int nGroup;
        cin>>nGroup;
        
        string delGroup;
        string delTeams;
            
    
        for(int i=0;i<nGroup;i++)
        {
            cout<<"What name for Group "<<i+1<<"?"<<endl;
    
            char GrpName[300];
          
            fflush(stdin);
            
            cin.getline(GrpName,30);
            string FileName=GrpName;
            //create a string to delete the Group file
            string copyFileName=FileName;
            int indexGroup=copyFileName.find_first_of(' ');
            copyFileName.erase(indexGroup);
            delGroup="del "+copyFileName+"*";
            fstream Group(FileName.c_str(), ios_base::in);// attempt open for read
            if (!Group)
            {
                // file doesn't exist; create a new one
                Group.open(FileName.c_str(), ios::out|ios::binary|ios::app);
    
                cout<<"Lets input team names..."<<endl;
                cout<<"How many teams?"<<endl;
                int nTeam;
                cin>>nTeam;
    
                for(int j=0;j<nTeam;j++)
                {
                    cout<<"What name for team "<<j+1<<"?"<<endl;
                    
                    char TeamName[300];
                    
                    fflush(stdin);
                    cin.getline(TeamName,30);
                    Group<<TeamName<<"\n";
                    
                    string sTeam=TeamName;
                    //create a string to delete the team file and team extended files
                    string copysTeam=sTeam;
                    int indexTeam=copysTeam.find_first_of(' ');
                    copysTeam.erase(indexTeam);
                    delTeams="del "+copysTeam+"*";
    
                    string sTeamEx=sTeam + "ex";
                    
                    fstream Team(sTeam.c_str(), ios_base::in);// attempt open for read
                    if (!Team)
                    {
                        // Team doesn't exist; create a new one
                        Team.open(sTeam.c_str(), ios::out|ios::binary|ios::app); 
                        Team.close();
                    }
                    else //ok, Team exists; error message
                    {
                        cout<<"ERROR, the Team already exists"<<endl;
                    }
                    
                    fstream TeamEx(sTeamEx.c_str(), ios_base::in);// attempt open for read
                    if (!TeamEx)
                    {
                        // Team Extended doesn't exist; create a new one
                        TeamEx.open(sTeamEx.c_str(), ios::out|ios::binary|ios::app); 
                        TeamEx.close();
                    }
                    else //ok, Team Extended exists; error message
                    {
                        cout<<"ERROR, the Team Extended already exists"<<endl;
                    }
    
                }
                Group.close();            
            }
            else //ok, group exists; show the error message
            {
                cout<<"ERROR, the group already exists"<<endl;
            }         
        }
        cout<<"Do you want to clean up all files created ?(y/n)"<<endl;
        char YesNo[1];
        cin>>YesNo[0];
        if(YesNo[0]=='y'||YesNo[0]=='Y')
        {
            cout<<"deleting all files created"<<endl;
            cout<<"deleting Group files..."<<endl;
            system(delGroup.c_str());
            cout<<"deleting Team files and Team Extended files..."<<endl;
            system(delTeams.c_str());
        }
        
        getch();
        return 0;
    }
    let say group name --> GroupA
    result --> program suddenly quit

    let say group name --> Group A
    result --> the program continue

    why is this happened ?

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> why when i inserted group name without space,the program suddenly quit.
    Maybe because your code looks for the first space in the group name when it uses the code:
    Code:
    int indexTeam=copysTeam.find_first_of(' ');
    But if there is no space that will return -1. You then call erase with -1 as an argument, which might be crashing the program. YOu should compare indexTeam with string::npos, and only erase if they is not equal.

    >> fflush(stdin);
    Why is this there? Besides being bad practice in C, there is no reason to use it in C++. The first fix suggested, adding cin.ignore() after the call to cin>>nGroup; is the better way to go.

  14. #14
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    fflush(stdin);

    the function is same with cin.ignore()

    i still have no idea to use string::npos

    maybe someone can show me some example.

  15. #15
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> the function is same with cin.ignore()
    No, it is not the same. Use cin.ignore().

    >> i still have no idea to use string::npos
    Do you know how to compare two values in an if statement? Make an if statement that compares indexTeam and string::npos and enters the if block if those two values are not equal. How would you do it if I said to compare indexTeam to -1? The code would be the same except you'd replace -1 with string::npos.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. compare structures
    By lazyme in forum C++ Programming
    Replies: 15
    Last Post: 05-28-2009, 02:40 AM
  2. OOP Question DB Access Wrapper Classes
    By digioz in forum C# Programming
    Replies: 2
    Last Post: 09-07-2008, 04:30 PM
  3. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  4. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM