Thread: structures and string

  1. #1
    Registered User
    Join Date
    Apr 2005
    Posts
    6

    structures and string

    Simple question. In the program below, what if name of the company is larger than 20 characters. How can I do to printout the name up to 20 and ignore the rest. As is, if the name is more than 20 character will printout up to 20 and ends the program.


    #include <iostream>
    using namespace std;

    struct pizza
    {
    char name[20;
    float diameter;
    double weight;

    };

    int main ()

    {

    pizza first =
    {
    "init",
    0,
    0
    };
    cout << "Company name";
    cout << "\n";
    cin >> first.name;
    cout << "\n";
    cout << "Enter the pizza diameter";
    cout << "\n";
    cin >> first.diameter;
    cout << "\n";
    cout << "Enter the pizza weight";
    cout << "\n";
    cin >> first.weight;
    cout << "\n";
    cout << "\n";
    cout << "Your Pizza Company name is: "<< first.name << "\n";
    cout << "The diameter of the pizza is: "<< first.diameter << " Inches"<< "\n";
    cout << "The weight of the pizza is: "<< first.weight << " Pounds" << "\n";
    cout << "\n";
    return 0;
    }

  2. #2
    Registered User
    Join Date
    May 2003
    Posts
    82
    I just ran it (sans missing end bracket on name), and it worked. It read in first 20 characters and ignored the rest when assigning name. Seemed to have the same behavior as when I used a name that was under 20.

    Could you describe the problem in more detail?

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    RE-EDIT: this whole post is inaccurate. maybe i should quit drinkin

    try this
    cout << strncpy(&first.name, &first.name, 20);


    besides first.name[20] will only hold 20 characters anyway - that include the '\0'


    EDIT: the following is inaccurate
    cin knows how many characters name can hold, and will only write up to that many characters - 1. the -1 is '\0'. well, actually, cin will write that one too

    Correction: cin will resize your character arrays
    Last edited by misplaced; 04-07-2005 at 01:32 AM.
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  4. #4
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    ....i just re-read your original post - it doesn't make much sense

    How can I do to printout the name up to 20 and ignore the rest. As is, if the name is more than 20 character will printout up to 20 and ends the program.
    just what exactly do you want?
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  5. #5
    Registered User
    Join Date
    May 2003
    Posts
    82
    Now I'm curious. I ran this, and checked strlen() immediately after input, which gave lengths greater than the size of the array. Is the program writing past it's bounds?

    If so, you might want to use a string class, or a more sophisticated get- function assuming you want predictable behavior when the user excedes 20 characters of input.

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    In the program below, what if name of the company is larger than 20 characters.
    Your program will either crash when you try to output the name, or you will get a bunch of junk characters after the name. If you want to know why, see my post in this thread:

    http://cboard.cprogramming.com/showthread.php?t=63956

    How can I do to printout the name up to 20 and ignore the rest.
    Like this:
    Code:
    char name[20];
    cout<<"enter a name: ";
    cin.getline(name, 20);  //standard method of reading data into a char array
    	
    cout<<name<<endl;
    Note: getline() will read in 19 chars and put a '\0' in the last position of the array. The '\0' is necessary to output char arrays using cout<<. If you want to read in 20 chars, then make your array size 21, and put 21 in getline(). If the user enters less than 20 chars, then getline() will put a '\0' after the last character of input, and only the number of chars read in will be output when you use cout<<.
    Last edited by 7stud; 04-07-2005 at 02:08 AM.

  7. #7
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    i was wrong - cin will resize character arrays - i'm not sure what i was thinking.

    perhaps you want to use char * name; rather than char name[20];
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    i was wrong - cin will resize character arrays
    Nope. Read the link I posted for more info. strlen() is going out of bounds. <cstring> functions only work on cstrings, i.e. char arrays that end with a '\0'. All <cstring> functions use loops to traverse the char array, and the '\0' indicates the end of the char array:
    Code:
    int i = 0;
    while(theCharArray[i] != '\0')
    {
         //do something with theCharArray
         i++;
    }
    The <<operator does the same thing to output char arrays. There is no array bounds checking in C++, so you can go out of bounds and C++ will not complain.

    If the user enters more than 20 chars, then the >>operator will happily fill the entire array with input, so there will be no terminating '\0'. If there are less than 20 chars, it looks like the >>operator enters a '\0' after the last char of the input, so the <<operator will display the output correctly.

    Therefore, you don't use the >>operator, e.g. cin>>, to read input into char arrays.
    Last edited by 7stud; 04-07-2005 at 02:10 AM.

  9. #9
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    ha - i should know better than to use VC to test my code

    MS-VC++ 6.0
    code:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    	char * name;
    	cout << '>';
    	cin >> name;
    	cout << name << ' ' << strlen(name) << endl;
    
    	char *p = name;
    	while(*p)
    	{
    		cout << *p;
    		p++;
    	}
    	cout << endl;
    
    	return 0;
    }
    output:
    Code:
    >abcdefg
    abcdefg 7
    abcdefg
    Press any key to continue

    Dev-c++ seg faults
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  10. #10
    Registered User
    Join Date
    Apr 2005
    Posts
    6
    Thank you every one for answer.

    The problem is that if I type more than 20 characters the program will just print out the name up to 20, and that is fine, but will ignore the rest of the program

    Example: if I change "cin" for "cin.get(first.name, 10)"

    Company name
    This test is only with 10 characters

    Enter the pizza diameter

    Enter the pizza weight


    Your Pizza Company name is: This test
    The diameter of the pizza is: 0 Inches
    The weight of the pizza is: 0 Pounds

    Press any key to continue
    It jumps the diameter and weight and prints out "0" for both.

    Example using a name with less than 10 characters

    Company name
    Nine

    Enter the pizza diameter
    23

    Enter the pizza weight
    34


    Your Pizza Company name is: Nine
    The diameter of the pizza is: 23 Inches
    The weight of the pizza is: 34 Pounds

    Press any key to continue

    If the person that is typing does not know that the limit is 20(or 10) will type a name more than the limit and the rest of the program will not execute
    Last edited by puckparches; 04-07-2005 at 09:26 PM.

  11. #11
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    The reason this happens is because the get will extract the first 9 characters from the stream "This test" and will leave the remainder still in the stream. Then when you ask for the pizza diameter (which is a float), cin will attempt to process the remainder of what is left in the input stream, the " is only with 10 characters" part. The problem with this is that cin will go into an error state once it tries to convert "is" into a float and the cin will exit without doing anything, the "is" won't even be extracted from the input stream. Later, you ask the user for the pizza weight and again try to use cin to get this value. But, since cin was put into the error state previously (and is still in an error state), the extraction automatically fails. The effect of this is that it appears to you, the user, that the program is not letting you enter in any input for these two values.

    If you expect the user to enter more data than you are going to accept for the name, there are two courses of action you should consider. The best course would be to use a string container instead of a char array to store this information. The string container will allow you to store however much data you need it to.

    Code:
    #include <string>
    
    ...
    
    struct pizza
    {
    string name;
    float diameter;
    double weight;
    };
    
    ...
    
    cout << "Company name\n";
    getline(cin,first.name);
    If you are set on using a char array, then you should probably call the ignore member function after the first cin.

    Code:
    #include <limits>
    
    ...
    
    cout << "Company name\n";
    cin.get(first.name,10);  // Test only getting first 9 characters and skipping rest of input
    cin.ignore(numeric_limits<streamsize>::max(),'\n');
    cout << "\nEnter the pizza diameter\n";
    cin >> first.diameter;
    
    etc...
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  12. #12
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    All the input data the user enters is gathered up and saved--whether you read it or not--and any unread input is first in line to be read by any subsequent reads. Any new data the user enters gets put in line behind any data you didn't read before.

    That presents big problems when you try to read in a number and there are characters left over from prior input. You have to decide how you want to handle that. The easiest way is to ignore() any data you don't read in. The ignore() function will ignore the number of characters specified between the parentheses or until a '\n' character(= a newline) is encountered in the input. When the user hits return to enter the input, an invisible newline character is entered at the end of the input. So, you want to ignore everything up to that newline char, and you can do that by specifying a huge number for ignore().

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with Data structures: Hash tables
    By Shaun32887 in forum C++ Programming
    Replies: 18
    Last Post: 07-02-2008, 04:47 PM
  2. rewriting my server
    By xixpsychoxix in forum Networking/Device Communication
    Replies: 5
    Last Post: 07-01-2008, 07:50 PM
  3. Nested Structures - User Input
    By shazg2000 in forum C Programming
    Replies: 2
    Last Post: 01-09-2005, 10:53 AM
  4. Modifying info on Exe & Dll's
    By johnd in forum Windows Programming
    Replies: 9
    Last Post: 11-16-2003, 12:49 PM