Structs:

This is a discussion on Structs: within the C++ Programming forums, part of the General Programming Boards category; This is a homework assignment but I am doing a little extra. Mainly because I like to call functions in ...

  1. #1
    Registered User
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    487

    Structs:

    This is a homework assignment but I am doing a little extra. Mainly because I like to call functions in main and keep it as clear as I can. With that being said, I am having an issue passing input from a struct from one function to another. Also the array is failing but when I did the same thing in initially when I first declared it it was fine, why?

    Code:
     #include <iostream>
    
    using namespace std;
    
    void HW_step1and3();
    void HW_step_4();
    void print_HW4();
    
    const char name_size = 20;
    
    struct StudentRecord {
        char Name[name_size];
        int ID;
        float GPA;
    };
    
    void HW_step1and3()
    {
        StudentRecord TESCStudent;
        
        TESCStudent.Name[name_size]= {"SuperProgrammer"};  //When I used it in the struct itself it was fine. Now I get an error
        TESCStudent.ID=1234;
        TESCStudent.GPA=4.0;
        
        for (size_t i=0; i<sizeof(TESCStudent.Name); i++) {
             
            cout<< TESCStudent.Name[i];
            
        }
                cout<<"\n" <<TESCStudent.ID<<endl;
                cout<< TESCStudent.GPA<<endl;
                cout<<" "<<endl;
    }
    
    void HW_step_4()
    {
        StudentRecord TESCStudent;
    
        cout<<"Please enter the Students Name:"<<endl;
        cin>>TESCStudent.Name;
        
        cout<<"Please Enter the Students ID Number:"<<endl;
        cin>>TESCStudent.ID;
        
        cout<<"Please Enter the students GPA"<<endl;
        cin>>TESCStudent.GPA;
        
        print_HW4(struct TESCStudent.name,struct TESCStudent.ID,struct TESCStudent.GPA);
    }
    
    void print_HW4(struct char, struct int, struct float)  // this was a real reach, I have good feeling its wrong
    {
        
        //I'll print the above here
    
    }
    
    int main(int argc, const char * argv[])
    {
        HW_step1and3();
        
        HW_step_4();
        
        return 0;
    }

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,020
    So a couple of things...
    First, do not use char arrays for strings. There is a string class named std::string. Use it. For your own sanity and for others security.

    >>TESCStudent.Name[name_size]= {"SuperProgrammer"};
    This is wrong in four ways:
    - You are trying to initialize a member of a struct. You cannot do this. You can only initialize members when you create the struct. Basically, MyStruct Hello = { /* my values in here */ }
    - You are trying to assign an array of characters to a single element (ie one char). How do you propose to do that?
    - You are accessing element name_size which is out of bounds. Valid indexes are 0 to name_size - 1.
    - {} means an initializer list in C++11, but you are trying to assign an initializer list to one element, one char. That's wrong. Even if it wasn't a single element, you can't assign an initializer list (which is a type of std::initializer_list) to a char array.
    Yes, I can see the horror on your face, but it's not so difficult. You are making it hard on yourself by using char arrays. If you switch Name to a std::string, then all you have to do is TESCStudent.Name = "SuperProgrammer". Easy, right? Natural, right? No gotchas. Easy, pweasy.

    >>cout<< TESCStudent.Name[i];
    std::cout understands string, so you can simply do cout<< TESCStudent.Name and remove the loop.

    >>cin>>TESCStudent.Name;
    Never ever read into a char array using std::cin like this. Make it easy on yourself; use std::getline combined with an std::string. No gotchas. It's easy and you have nothing to worry about. What you are doing will most likely cause a buffer overflow (google it!).

    >>print_HW4(struct TESCStudent.name,struct TESCStudent.ID,struct TESCStudent.GPA);
    To pass arguments to a function, you type the names of the variables you want to pass. So remove the "struct" stuff.

    >>void print_HW4(struct char, struct int, struct float)
    This makes no sense. What types are these arguments? Are they some kind of structs? Are they chars, ints and floats? And where is the name of the parameters?
    Maybe you should look how to declare a function which takes arguments.


    Oh, and here is some good-to-know stuff.
    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.

  3. #3
    Registered User
    Join Date
    Apr 2013
    Posts
    1,342
    The instance of TESCStudent in HW_step1and3 is a different instance than the one in HW_step_4. You should declare a single instance of TESCStudent in main, and then pass a pointer to TESCStudent as a parameter to the functions that main calls. Structs with a basic type, like "struct char" are not allowed. Just use char, int, float, or pass a pointer to TESCStudent as a parameter to print_HW4.

  4. #4
    Registered User
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    487
    Thank you for the help guys. I would love to use stings and simply getline but I was told i had to use an array. I even e-mailed him and he told me to "Follow the assignment instructions".

    Ok, so I go the programing working but I wanted to use the new c++11 array format and not
    Code:
    cout<<"Please enter the Students Name:"<<endl; cin>>TESCStudent.Name;
    is failing.

    I am going to clean this code up and put it all in functions. I just wanted to get it to work and from there break it down since it is such a small program. I think it would look a lot neater if I used functions.

    Code:
    #include <iostream>
    #include <array>
    using namespace std;
    
    void HW_step1and3();
    void HW_step_4();
    void print_HW4();
    
    const size_t name_size = 20;
    
    struct StudentRecord {
        array<char, name_size> Name = {"SuperProgrammer"};
        int ID=1234;
        float GPA=4.0;
    }TESCStudent;
    
    
    int main(int argc, const char * argv[])
    {
        
        for (char student: TESCStudent.Name) {
        cout<< student;
        }
    
        cout<<"\n" <<TESCStudent.ID<<endl;
        cout<< TESCStudent.GPA<<endl;
        cout<<" "<<endl;
        
        
        cout<<"Please enter the Students Name:"<<endl;
        cin>>TESCStudent.Name;                           //failing
        
        cout<<"Please Enter the Students ID Number:"<<endl;
        cin>>TESCStudent.ID;
        
        cout<<"Please Enter the students GPA"<<endl;
        cin>>TESCStudent.GPA;
        
        
        for (char student: TESCStudent.Name) {
            cout<< student;
        }
        
        cout<<"\n" <<TESCStudent.ID<<endl;
        cout<< TESCStudent.GPA<<endl;
        cout<<" "<<endl;
    
    
        return 0;
    
    }



  5. #5
    Registered User
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    487
    Think I figured it out but I am back to having issues with HW_task4 when I call it in HW_task3. I do not have to use functions but since I ran into this issue I really would like to figure out what the heck the deal is.

    Code:
     #include <iostream>
    #include <array>
    using namespace std;
    
    void HW_task2();
    void HW_task3();
    void HW_task4();
    
    const size_t name_size = 20;
    
    struct StudentRecord {
        array< char, name_size> Name = {"SuperProgrammer"};
        int ID=1234;
        float GPA=4.0;
    }TESCStudent;
    
    void HW_task2()
    {
    
        for (char student: TESCStudent.Name) {
            cout<< student;
        }
        
        cout<<"\n" <<TESCStudent.ID<<endl;
        cout<< TESCStudent.GPA<<endl;
        cout<<" "<<endl;
    
    
    }
    
    void HW_task3()
    {
    
        cout<<"Please enter the Students Name:"<<endl;
        cin>>(TESCStudent.Name[name_size]);
        
        cout<<"Please Enter the Students ID Number:"<<endl;
        cin>>TESCStudent.ID;
        
        cout<<"Please Enter the students GPA"<<endl;
        cin>>TESCStudent.GPA;
        
        HW_task4(TESCStudent.Name[name_size],TESCStudent.ID,TESCStudent.GPA);
       
    
    }
    
    void HW_task4(char,int,float)
    {
        for (char student: TESCStudent.Name) {
            cout<< student;
        }
        
        cout<<"\n" <<TESCStudent.ID<<endl;
        cout<< TESCStudent.GPA<<endl;
        cout<<" "<<endl;
    
    }
    
    int main(int argc, const char * argv[])
    {
        
        HW_task2();
        
        HW_task3();
        
        HW_task4();
       
    
    
        return 0;
    
    }

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    2,919
    Your function call, function implementation and function prototype must all agree as to the number and type of parameters.

    Also you need to add some variable names to your function implementation.

    Why are you using std::array for C-strings? The std::array class is not suited for use with C-strings.

    Do you know the difference between a char and an array of char?

    Do you realize that the following is trying to retrieve one single character into your array, not a string. And that you are accessing your array out of bounds. Arrays in C/C++ start at zero and stop at size - 1. You're trying to access array[size] which is out of bounds.

    Finally why the global variable (TESCStudent)? You need to learn to properly pass local variables to and from your functions as required.

    Jim

  7. #7
    Registered User
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    487
    I dont want to use an array but I was told to. I have to use TESCStudent so I figured I would put it global so I didn't have to keep writing it.

    Out of bounds? You mean if I put in more then one letter and a name?

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    2,919
    Out of bounds?
    Out of bounds because you try to access your array past the end of the array. You defined your array with a size of name_size so when you try to access name_size you're accessing your array out of bounds. Arrays stop at size - 1!

    I dont want to use an array but I was told to.
    That's fine, but you can't use std::array to hold C-strings you need to use old fashioned C style arrays.

    How about answering the rest of the questions as well. Do you know the difference between a single character and an array or character?

    I really suggest you read up a little more about char and char []. Start with these links: Arrays and Character Sequences.

    I have to use TESCStudent so I figured I would put it global so I didn't have to keep writing it.
    Quit being so lazy, make it a local variable in main() and properly pass this variable to your functions.


    Jim
    Last edited by jimblumberg; 09-25-2013 at 01:28 PM.

  9. #9
    Registered User
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    487
    A single Character is just that a single character like 'c' and an array can hold variables of any kind in address or locations like PO box would.

  10. #10
    Registered User
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    487
    I have everything working but the array.

    Code:
     void HW_task1()
    {
        TESCStudent.Name[SIZE] = {'S','u','p','e','r','P','r','o','g','r','a','m','m','e','r'};
        TESCStudent.ID=1234;
        TESCStudent.GPA=4.0;
        
        for (int i=0; i<SIZE; i++) {
            
            cout<<TESCStudent.Name[i];
        }
        cout<<"\n" <<TESCStudent.ID<<endl;
        cout<< TESCStudent.GPA<<endl;
        cout<<" "<<endl;
    
    
    }

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,020
    >>TESCStudent.Name[SIZE] = {'S','u','p','e','r','P','r','o','g','r','a','m',' m','e','r'};
    You were told why this does not work. The same still applies even now.
    You need to use strcpy if you intend to use C-strings. But you really should pressure your teacher to teach modern C++.
    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.

  12. #12
    Registered User
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    487
    I forgot all about strcpy from C... Thank you... This is what I ended up using to get it to work. Pretty messy huh?

    Code:
      TESCStudent.Name[0]='S';
        TESCStudent.Name[1]='u';
        TESCStudent.Name[2]='p';
        TESCStudent.Name[3]='e';
        TESCStudent.Name[4]='r';
        TESCStudent.Name[5]='P';
        TESCStudent.Name[6]='r';
        TESCStudent.Name[7]='o';
        TESCStudent.Name[8]='g';
        TESCStudent.Name[9]='r';
        TESCStudent.Name[10]='a';
        TESCStudent.Name[11]='m';
        TESCStudent.Name[12]='m';
        TESCStudent.Name[13]='e';
        TESCStudent.Name[14]='r';
    TESCStudent.Name[15]='\0';
    now it is

    Code:
     void HW_task1_2(){
    char str1[]="Super Programer";
    
    strcpy(TESCStudent.Name,str1);
    
     for (int i=0; i<SIZE; i++) {
    
     cout<<TESCStudent.Name[i];
        }
     cout<<"\n" <<TESCStudent.ID<<endl;
    cout<< TESCStudent.GPA<<endl;
     cout<<" "<<endl;
    
    
    }
    Last edited by jocdrew21; 09-25-2013 at 03:03 PM.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,020
    If TESCStudent is an std::array<char, N>, then you can probably do something like

    Code:
    static const char Tmp[] = "SuperProgrammer";
    assert(TESCStudent.Name.size() >= sizeof(Tmp));
    std::copy(Tmp, Tmp + sizeof(Tmp), TESCStudent.Name.begin());
    (Not tested.)
    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.

  14. #14
    Registered User
    Join Date
    May 2010
    Posts
    2,919
    Pretty messy huh?
    Very!

    What's wrong with something like:

    Code:
       char array[name_size] = "SuperProgrammer";
    Jim

  15. #15
    Registered User
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    487
    Jim I tired that but it failed. This is what I have now and I feel pretty solid about it. What do you guys think?

    Once again thank you very much. I seem to learn more on this site then I do in my class.

    Code:
     #include <iostream>
    #include <string>
    
    #define SIZE 20
    using namespace std;
    
    void HW_task2();
    void HW_task3();
    
    
    
    struct StudentRecord {
        char Name[SIZE];
        int ID;
        float GPA;
    }TESCStudent;
    
    void HW_task1_2()
    {
        char str1[]="Super Programer";
        
    	strcpy(TESCStudent.Name,str1);
        cout<<"Students Name: ";
        for (int i=0; i<sizeof(str1)-1; i++) {
            
            cout<<TESCStudent.Name[i];
        }
        
        TESCStudent.ID=1234;
        TESCStudent.GPA=4.0;
        
        cout<<"\nStudents ID: " <<TESCStudent.ID<<endl;
        cout<<"Students GPA "<<TESCStudent.GPA<<endl;
        cout<<" "<<endl;
        
        
    }
    
    void HW_task3_4()
    {
        for(int i=0;i<SIZE;i++)
            TESCStudent.Name[i]='\0';
        
        cout<<"Please enter the Students Name:"<<endl;
        cin.getline(TESCStudent.Name,20,'\n');
        
        cout<<"Please Enter the Students ID Number:"<<endl;
        cin>>TESCStudent.ID;
        
        cout<<"Please Enter the students GPA"<<endl;
        cin>>TESCStudent.GPA;
        
        cout<<"Students Name ";
    	for (int i=0;i<sizeof(TESCStudent.Name);i++)
    	{
      cout<<TESCStudent.Name[i];
    	}
        
        cout<<"\nStudents ID: " <<TESCStudent.ID<<endl;
        cout<<"GPA: "<<TESCStudent.GPA<<endl;
        cout<<" "<<endl;
        
    }
    
    
    int main(int argc, const char * argv[])
    {
        
        HW_task1_2();
        
        HW_task3_4();
        
        return 0;
        
    }

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 01-08-2013, 07:55 AM
  2. Typedef Structs inside Typdef structs
    By gremory in forum C Programming
    Replies: 21
    Last Post: 12-30-2011, 07:48 PM
  3. [ noob question ] Help with structs within structs
    By Riverfoot in forum C Programming
    Replies: 3
    Last Post: 04-26-2011, 08:24 PM
  4. Passing Structs Into An Array Of Structs.
    By TheTaoOfBill in forum C Programming
    Replies: 3
    Last Post: 10-07-2010, 10:38 AM
  5. passing structs & pointers to structs as arguments
    By Markallen85 in forum C Programming
    Replies: 6
    Last Post: 03-16-2004, 07:14 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21