Thread: Where am I going wrong?

  1. #1
    Registered User
    Join Date
    Aug 2004
    Posts
    13

    Where am I going wrong?

    I am writing a program for my C++ class but I am getting a lot of errors. We are dealing with the new concept of arrays and structures.

    I get errors in my functions regarding undeclared indentifiers and incorrect "lvalue."

    ************************************************
    Code:
    #include <iostream.h>
    #include <fstream.h>
    #include <ctype.h>
    #include <cstring>
    typedef char str[30];
    
    
    // This program will read an array of structures from a file, and allow the user to
    // Issue commands to list the students, or all grades.
    
    
    struct studentgrades
    	{
    		str name;
    		char grade;
    	}s;
    
    
    // Read file function
    // This function should create the studentgrades struct called 's', open a txt file, and stream the 
    // text file into the struct 's'.  The file is then closed.
    
    int Readfile (/*out*/ studentgrades s[], /*in*/ int i)
    	{
    		char fn[30];
    		cout << "Enter file name of student records:" << endl;
    		cin >> fn;
    		ifstream infile(fn,ios::nocreate);
    		i=0;
    		if (infile)
    			{while(!infile.eof())
    				{
    				infile >> s[i].name >> s[i].grade;
    				i++;
    				}
    				infile.close ( );
    			}
    		else cout << "Invalid file.  Please enter a valid file name." << endl;
    		return i;
    	}
    
    // Sort by name function
    // This function should create an
    
    void Sortbyname(/*in*/ int count)
    	{
    		str n[count];
    		for (int i=0; i < count-1; i++) 
    			for (int j=0; j<count-1; j++)
    				if (strcmp(s[j+1].name, s[j].grade) < 0)
    					{					
    					n=s[j].name;
    					s[j].name=s[j+1].name;
    					s[j+1].name=n;
    					str g=s[j].grade;
    					s[j].grade=s[j+1].grade;
    					s[j+1].grade=g;
    					};
    	}
    
    //Sort by grade function
    
    void Sortbygrade (/*in*/ int count)
    	{
    		str n[count];
    		for (int i=0; i< count-1; i++) 
    			for (int j=0; j<count-1; j++)
    				if (s[j+1].grade < s[j].grade)
    					{
    						n=s[j].name;
    						s[j].name=s[j+1].name;
    						s[j+1].name=n;
    						str g=s[j].grade;
    						s[j].grade=s[j+1].grade;
    						s[j+1].grade=s[j].grade;
    					}
    	}
    
    //List function
    
    void List (/*in*/ int i)
    {
    	char menu;
    	cout << "List A)lphabetically or by G)rade?" << endl;
    	cin >> menu;
    	switch(menu=toupper(menu)){
    	case 'A': 
    		Sortbyname(int i);
    		break;
    	case 'G': 
    		Sortbygrade(int i);
    		break;
    	}
    	for (int i=0; i<=count; i++)
    		cout << s.name[i] << '\t' << s.grade[i] << endl;
    }
    
    //Count grades function
    
    void Grades (/*in*/ int count)
    	{
    		int a=0;
    		int b=0;
    		int c=0;
    		int d=0;
    		int f=0;		
    		char grades;
    
    		for (int i=0; i < count; i++)
    			switch (s.grade[i]=toupper(grades))
    			{
    				case 'A':
    					a++;
    					break;
    				case 'B':
    					b++;
    					break;
    				case 'C':
    					c++;
    					break;
    				case 'D':
    					d++;
    					break;
    				case 'F':
    					f++;
    					break;
    			};
    		cout << "Total number of grade A:" << a << endl;
    		cout << "Total number of grade B:" << b << endl;
    		cout << "Total number of grade C:" << c << endl;
    		cout << "Total number of grade D:" << d << endl;
    		cout << "Total number of grade F:" << f << endl;
    	}
    
    //Main function
    
    int main (void)
    	{
    		int count=0;
    		char cmd;
    		do{
    			cout << "Please enter a command: R)ead L)ist G)rades Quit" << endl;
    			switch (cmd=toupper(cmd)){
    				case 'R':
    					cout << Readfile(count)<< "records read into memory.";
    					break;
    				case 'L':
    					List(count);
    					break;
    
    				case 'G':
    					Grades(count);
    
    				case 'Q':
    					break;
    
    				default:
    					cout << "Invalid command.";
    			}
    		} while (cmd !='Q');
    			return 0;
    }
    Last edited by derrick; 08-31-2004 at 09:12 AM.

  2. #2
    I'm less than sure.... abyssphobia's Avatar
    Join Date
    Aug 2004
    Posts
    112
    firstly as well as I can see you are missing using namespaces std;

    Code:
    #include <iostream>
    #include <fstream.h>
    #include <ctype.h>
    #include <cstring> // because this is standar
    using namespaces std;
    I keep checking, ok!, well and I also suggest to use code tags.
    Have I crossed the line?

  3. #3
    I'm less than sure.... abyssphobia's Avatar
    Join Date
    Aug 2004
    Posts
    112
    use this header
    #include <stdlib> or <cstdlib>

    Code:
    case 'Q':
    exit(0); // use that for finish your program, mmm well it works fine in visual C++
    break;
    seems good for me!!!. Sorry but I can test your program Im in the college and dont have compiler
    Have I crossed the line?

  4. #4
    Inverse Tangent Studios
    Join Date
    Aug 2004
    Posts
    4
    what compiler are you using? that would help me to find your errors.

    one cause for an incorrect "lvalue" is when you try to change the value of a constant. for exampe:
    Code:
    const int SIX=6;
    SIX = 7;    //error- incorrect lvalue
    you may also see this error if the compiler doesn't know what a variable is (the variable hasn't been defined yet, or the type is unknown). different compilers may have different causes for that error. again, if you tell me what compiler you're using, i may be able to track down a few causes for errors.

  5. #5
    i dont know Vicious's Avatar
    Join Date
    May 2002
    Posts
    1,200
    Code:
    switch (cmd=toupper(cmd)){
    are these the lines your getting the error?

    I dont know why but that just looks odd.

  6. #6
    Cheesy Poofs! PJYelton's Avatar
    Join Date
    Sep 2002
    Location
    Boulder
    Posts
    1,728
    Some big problems that I see:

    Code:
    str n[count];
    You can't define the size of an array like this, you must use a constant. The compiler needs to know how much space to allocate for the array at compile time, and at compile time count is an unknown value.

    Second, you keep treating s as an array when it is defined as only a single instance.

    Last, and I admit I am not familiar with cstrings since I've only really used strings before, but I'm pretty sure you cannot simply assign a cstring to another cstring using only an "=" sign. I think you need a special cstring function to do this, and I'm sure thats the cause of your lvalue errors.

  7. #7
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    I would be glad to help, but it would be a LOT easier if you put comments beside the lines that cause the errors.

    But here's some things I'd like to point out:
    >>i=0; (in ReadFile)
    You pass a value to the function, then set it to 0 without ever using it...

    In sortbyname():
    Code:
    n=s[j].name;
    s[j].name=s[j+1].name;
    s[j+1].name=n;
    str g=s[j].grade;
    s[j].grade=s[j+1].grade;
    s[j+1].grade=g;
    The first line is probably causing an error. 'n' is an array of 30 str's, while s[j+1].name is just one str. Aside from that syntax error, you have the problem that you CANNOT simply assign strings like that; you must use strcpy() to copy the contents of the string. The same goes for g=, s[j].grade=, etc... I believe you have the same problem in the other sorting function too.

    If you want to use strings like that, and use = to assign strings etc. then you'll have to look into std::string or string, in <string> and <string.h> respectively (the new standard headers don't have .h, but if you have an old compiler then don't worry about it). They're the standard C++ library strings.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  8. #8
    Registered User
    Join Date
    Aug 2004
    Posts
    13
    I am using MS Visual C++

    Here are the errors I am receiving:

    Cpp1.cpp
    c:\documents and settings\user\cpp1.cpp(49) : error C2664: 'strcmp' : cannot convert parameter 2 from 'char' to 'const char *'
    Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
    c:\documents and settings\user\cpp1.cpp(52) : error C2440: '=' : cannot convert from 'char [30]' to 'char [30][30]'
    There is no context in which this conversion is possible
    c:\documents and settings\user\cpp1.cpp(53) : error C2106: '=' : left operand must be l-value
    c:\documents and settings\user\cpp1.cpp(54) : error C2440: '=' : cannot convert from 'char [30][30]' to 'char [30]'
    There is no context in which this conversion is possible
    c:\documents and settings\user\cpp1.cpp(55) : error C2440: 'initializing' : cannot convert from 'char' to 'char [30]'
    There are no conversions to array types, although there are conversions to references or pointers to arrays
    c:\documents and settings\user\cpp1.cpp(57) : error C2440: '=' : cannot convert from 'char [30]' to 'char'
    This conversion requires a reinterpret_cast, a C-style cast or function-style cast
    c:\documents and settings\user\cpp1.cpp(63) : error C2065: 'count' : undeclared identifier
    c:\documents and settings\user\cpp1.cpp(68) : error C2106: '=' : left operand must be l-value
    c:\documents and settings\user\cpp1.cpp(69) : error C2106: '=' : left operand must be l-value
    c:\documents and settings\user\cpp1.cpp(70) : error C2106: '=' : left operand must be l-value
    c:\documents and settings\user\cpp1.cpp(71) : error C2440: 'initializing' : cannot convert from 'char' to 'char [30]'
    There are no conversions to array types, although there are conversions to references or pointers to arrays
    c:\documents and settings\user\cpp1.cpp(84) : error C2065: 'student' : undeclared identifier
    c:\documents and settings\user\cpp1.cpp(84) : error C2146: syntax error : missing ')' before identifier 's'
    c:\documents and settings\user\cpp1.cpp(84) : error C2059: syntax error : ')'
    c:\documents and settings\user\cpp1.cpp(87) : error C2275: 'str' : illegal use of this type as an expression
    c:\documents and settings\user\cpp1.cpp(10) : see declaration of 'str'
    c:\documents and settings\user\cpp1.cpp(87) : error C2146: syntax error : missing ')' before identifier 's'
    c:\documents and settings\user\cpp1.cpp(87) : error C2059: syntax error : ')'
    c:\documents and settings\user\cpp1.cpp(91) : error C2228: left of '.name' must have class/struct/union type
    c:\documents and settings\user\cpp1.cpp(91) : error C2228: left of '.grade' must have class/struct/union type
    c:\documents and settings\user\cpp1.cpp(103) : error C2065: 'grades' : undeclared identifier
    c:\documents and settings\user\cpp1.cpp(138) : error C2664: 'Readfile' : cannot convert parameter 1 from 'int' to 'struct studentgrades []'
    Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
    c:\documents and settings\user\cpp1.cpp(141) : error C2660: 'List' : function does not take 3 parameters
    c:\documents and settings\user\cpp1.cpp(145) : error C2660: 'Grades' : function does not take 2 parameters
    Error executing cl.exe.

    Cpp1.obj - 23 error(s), 0 warning(s)

  9. #9
    Hardware Engineer
    Join Date
    Sep 2001
    Posts
    1,398

    A couple of comments & suggestions.

    Cannot convert... errors -
    The array syntax can be confusing because once you define MyArray[n], then MyArray (without the brackets) is automatically defined as a pointer to the fist element of MyArray. If you use a single-subscript with a two-dimensional array, like MyArray[n], that becomes a pointer.

    When you get a "Cannot convert..." error, it's often caused by trying to assign an element-value to the pointer:
    MyArray = MyArray[3]; //wrong!
    MyArray = X; //wrong! (Unless X is a pointer)

    l-value errors -
    l-value means left-value. Something is wrong with the "variable" on the left side of the equal-sign. The "unknown", belongs on the left.

    X = 6; // l-value OK
    6 = X; // l-value error

    X = Y + 3; // l-value OK
    Y + 3 = X; // l-value error

    PROGRAM DEVELOPMENT & DEBUGGING - The real solution to your root-problem -
    It is very difficult (and frustrating) to debug a program with many errors!

    The error messages aren't always helpful. The compiler doesn't know what you're trying to do, and compilers are easily confused... You didn't want to "convert" anything, but the compiler "thought" that's what you were asking it to do. The first error message usually points to a line near the actual error. Linker-error messages don't reference line-numbers and they can be difficult to decipher.

    So, do NOT write your whole program before you compile and test it. Experienced programmers write and test small sections of the program at a time.

    Write one or two lines of code, and then test-compile and test-run your program. Debug as required. Add one or two more lines and test-compile, test-run, and debug again. As you gain experience and confidance you can write larger sections of code between test-compiles and test-runs.

    Now, it takes a bit of practice to learn how to develop your code in this way. Of course, you can't write the code to call a function before the function definition exists, etc.

    When you write a function, make an empty function first. If there is a return value, include a known "dummy" return value. Add a few lines of code at a time to the function body 'till it works completely.
    Last edited by DougDbug; 08-31-2004 at 05:39 PM.

  10. #10
    Registered User
    Join Date
    Aug 2004
    Posts
    13

    Unhappy

    Thanks.

    I found that part of my problem was an incorrect use of a struct type in my operations:

    Code:
    	
    void Sortbyname(/*in*/ int count)
    str n[count];
    if (strcmp(s[j+1].name, s[j].grade) < 0)
    	{					
    	        n=s[j].name;
    		s[j].name=s[j+1].name;
    		s[j+1].name=n;
    		str g=s[j].grade;
    		s[j].grade=s[j+1].grade;
    		s[j+1].grade=g;
    	};
    Where 's' is the variable of type 'struct'. DUH! Can't put a struct member of type 'char' into an 'int' variable, right?

    I changed it to this, passing the array of type 'struct' and creating a local struct variable called 'n' for use in sorting:

    Code:
    void Sortbyname(students s[], int count)
    if (strcmp(s[j+1].name, s[j].name) < 0)
    	{
    		students n;
    		n=s[j];
    		s[j]=s[j+1];
    		s[j+1]=n;
    	};

  11. #11
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>DUH! Can't put a struct member of type 'char' into an 'int' variable, right?
    Sure you can. A char is simply a small integer that we interpret differently

    I'm glad you got the problem solved though. But you should still remember, even though you typedef a char[30] as 'str', 'str' is not a normal datatype - it's still an array of characters, and therefore it behaves differently and cannot be assigned using the = operator; and I believe that may be why you got those l-value errors. A 'student' structure on the other hand CAN be copied using =, because it is a single object as opposed to an array, and none of its members are dynamically allocated; so the default copy operation will just copy the memory of the entire structure, which includes both the grade and the array of characters inside. And that's why your program works now
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  12. #12
    Registered User
    Join Date
    Jul 2003
    Posts
    450
    Code:
    case 'A': 
    		Sortbyname(int i);
    		break;
    	case 'G': 
    		Sortbygrade(int i);
    		break;
    This struck me as odd when calling the function you do not need to specify the type of the variable only when declaring and defining the function do you need to specify the type.

    Sortbyname(i); assuming it has been declared previously also a more discriptive name would help

    I don't know if this is an error but I have never seen it done.

  13. #13
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Good point, although I'm not sure if it's an error... perhaps it declares an unitialized variable called 'i' and passes that, sort of like a for loop Doesn't look like something that should EVER be done though.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 07-15-2004, 03:30 PM
  2. Debugging-Looking in the wrong places
    By JaWiB in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 11-03-2003, 10:50 PM
  3. Confused: What is wrong with void??
    By Machewy in forum C++ Programming
    Replies: 19
    Last Post: 04-15-2003, 12:40 PM
  4. God
    By datainjector in forum A Brief History of Cprogramming.com
    Replies: 746
    Last Post: 12-22-2002, 12:01 PM
  5. Whats wrong?
    By Unregistered in forum C Programming
    Replies: 6
    Last Post: 07-14-2002, 01:04 PM