Reading characters from a string and assigning them to a single char???

This is a discussion on Reading characters from a string and assigning them to a single char??? within the C++ Programming forums, part of the General Programming Boards category; Hi there, I'm having a bit of a mare. I am attempting to convert ROMAN NUMERALS into ARABIC NUMBERS... I ...

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    12

    Unhappy Reading characters from a string and assigning them to a single char???

    Hi there,

    I'm having a bit of a mare.

    I am attempting to convert ROMAN NUMERALS into ARABIC NUMBERS...

    I cannot for the life of me seem to be able to read a character from a string...

    I have been trying to write a 'SORT' function that uses a switch to sort through and count the different letters in a string that has been input either via the keyboard or from a file stream...

    Here is my full programme so far... any hints as to how I could read the letters would be a godsend... I have been doing this for about 20 huors straight and still can't get it!


    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    char LETTERS[16];
    int index;
    int REP;
    int fork;
    int countM, countD, countC,  countL,  countX,  countV,  countI;
    int	countCM, countCD, countXC, countXL, countIX, countIV;
    
    int valueM; int valueD; int valueC ; int valueL; int valueX;
    int valueV; int valueI; int valueCM; int valueCD; int valueXC;
    int valueXL; int valueIX; int valueIV;
    
    void READFILE ();
    void READKEYBOARD ();
    void SORT (char[]);
    void RESTART ();
    void COUNT (int);
    void COUNTLESS (int);
    void COUNTER (char []);
    void READLETTER2 (char[]);
    int TOTAL (int, int, int, int, int, int, int, int, int, int, int, int, int);
    
    
    int TOTAL (int m, int d, int c, int l, int x, int v, int i, int cm, int cd, int xc, int xl, int ix, int iv)   // TOTALS UP THE VALUES OF THE NUMERALS
    {
    	return (m+d+c+l+x+v+i+cm+cd+xc+xl+ix+iv);
    }
    
    void COUNTER (char counter[16])  // TALLIES AND ERROR CHECKS THE DOUBLE NUMERAL COUNTS
    {	
    	switch (counter[index])
    	{
    	case '\0':
    		break;
    	case 'D':
    		REP = 1; COUNTLESS(countC); COUNT(countCM); break;
    	case 'M':
    		REP = 1; COUNTLESS(countC); COUNT(countCD); break;
    	case 'C':
    		REP = 1; COUNTLESS(countX); COUNT(countXC); break;	
    	case 'L':
    		REP = 1; COUNTLESS(countX); COUNT(countXL); break;
    	case 'X':
    		REP = 1; COUNTLESS(countI); COUNT(countIX); break;
    	case 'V':
    		REP = 1; COUNTLESS(countI); COUNT(countIV); break;
    	default:
    		printf("You have input an invalid character");
    		RESTART ();
    	}
    }
    
    void COUNTLESS (int countless)			// CHECKS AND TALLIES THE SINGLE NUMERAL COUNTS
    {
    	(countless --);
    }
    
    void RESTART ()			// RESTARTS THE WHOLE PROGRAMME
    {
    	int yn;
    	printf("Do you wish to try again? Enter Y to continue \n(else enter anything else to quit): ");
    	scanf("%i", &yn);
    
    	if ((yn = 'Y')|| (yn = 'y'))
    		printf("Please quit and restart the programme");
    	else 
    	exit(0);
    }
    
    void SORT (char UNKNOWN[])		// DETERMINES WHICH NUMERALS HAVE BEEN ENTERED FROM THE STRING AND PERFORMS FUNCTION "COUNT" ON THEM
    {
    	switch (UNKNOWN[index])
    	{
    	case 'M':
    		REP = 4; COUNT(countM); break;
    	case 'D':
    		REP = 1; COUNT(countD); break;
    	case 'C':
    		REP = 3; COUNT(countC); READLETTER2(LETTERS); break;
    	case 'L':
    		REP = 1; COUNT(countL);	break;	
    	case 'X':
    		REP = 3; COUNT(countX); READLETTER2(LETTERS); break;
    	case 'V':
    		REP = 1; COUNT(countV); break;
    	case 'I':
    		REP = 3; COUNT(countI); READLETTER2(LETTERS); break;
    	default:
    			printf("You have input an invalid character"); RESTART ();
    	}
    }
    	 
    void READLETTER2 (char UNKNOWN[])		// READS THE SECOND THE SECOND NUMERAL AFTER THE PRIMARIES C, X and I AND PERFORMS TALL
    {	
    	index ++;	
    	COUNTER (LETTERS);
    }
    
    void COUNT (int count)			// CHECKS AND TALLIES THE SINGLE NUMERAL COUNTS
    {
    	(count ++);
    	if (count > REP)
    	{
    		printf("You have input too many consecutive numerals");
    		RESTART();
    	}
    }
    
    void READKEYBOARD ()			// FOR KEYBOARD MODE ASK FOR NUMERALS AND COPY INTO "LETTERS"
    {									//get the user to input a ROMAN NUMERAL SEQUENCE 
    	char Tab[16];						
    	printf("\n Please input your ROMAN NUMERALS from the keyboard (in CAPS only): ");
    	scanf("%s", &Tab);
    	strcpy(LETTERS, Tab);
    }
    
    void main ()
    {										// DECLARE VARIABLES ETC...
    	 int ANSWER;	 
    	 int c=0;
    	 int countM = 0; int countD = 0; int countC = 0; int countL = 0; int countX = 0; int countV = 0; int countI = 0;
    	 int	countCM = 0; int countCD = 0; int countXC = 0; int countXL = 0; int countIX = 0; int countIV = 0;
    	
    	// CHOOSE BETWEEN KEYBOARD & BATCH MODE
    
    	do 
    	{
    		printf("\n Choose 1 for FILE input");
    		printf("\n Choose 2 for KEYBOARD input: ");
    		scanf("%i", &c);
    	}	
    	while ((c <=0) || (c >=3));	
    	
    	if (c == 1)
    		printf("You have chosen one - file input");
    
    	else if (c == 2)
    	{
    		printf("You have chosen two - file input");	// FOR KEYBOARD MODE ASK FOR NUMERALS AND COPY INTO "LETTERS"
    		READKEYBOARD ();
    	}
    	
    	for (index = 0; LETTERS[index] != '\0'; index++);
    	SORT (LETTERS);
    
    	index = -1;
    
    	int valueM = 1000*countM; int valueD = 500*countD; int valueC = 100*countC; int valueL = 50*countL; int valueX = 10*countX;
    	int valueV = 5*countV; int valueI = 1*countI; int valueCM = 900*countCM; int valueCD = 400*countCD; int valueXC = 90*countXC;
    	int valueXL = 40*countXL; int valueIX = 9*countIX; int valueIV = 1*countIV;
    	
    	ANSWER = TOTAL(valueM, valueD,  valueC,  valueL,  valueX, valueV, valueI, valueCM,  valueCD, valueXC,  valueXL,  valueIX,  valueIV);
    
    	printf("The value you input in ROMAN NUMERALS was: %s", LETTERS);
    	printf("The equivalent value in Arabic numbers is: %i", ANSWER);
    
    }

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    Your program looks like C, but this is the C++ forum. Next time use the C forum.

    Code:
    void COUNTLESS (int countless)			// CHECKS AND TALLIES THE SINGLE NUMERAL COUNTS
    {
    	(countless --);
    }
    That function isn't going to affect the value of its parameter from the calling function. That is:
    Code:
    x = 3;
    COUNTLESS(x);
    // x is still 3
    If you want the changes to be reflected, declare the parameter to be a reference or a pointer.

    On the other hand, why do you need a function for such a simple operation?

    Same comments for COUNT().

    main() returns int, not void. See the FAQ.

    Code:
    	char Tab[16];						
    	printf("\n Please input your ROMAN NUMERALS from the keyboard (in CAPS only): ");
    	scanf("&#37;s", &Tab);
    	strcpy(LETTERS, Tab);
    Drop that &. And why not read directly into LETTERS?

    You can remove the "in CAPS only" restriction by using toupper() from <ctype.h> on each character in the string.

    Code:
    	if ((yn = 'Y')|| (yn = 'y'))
    		printf("Please quit and restart the programme");
    Use == for comparison, not =, which is for assignment. Also, tolower() or toupper() would make you job easier.
    Code:
    if(tolower(yn) == 'y')
    In TOTAL() you have this:
    Code:
    return (m+d+c+l+x+v+i+cm+cd+xc+xl+ix+iv);
    Perhaps you want something like this?
    Code:
    return (i) + (v*5) + (x*10) + (l*50) + /* ... */;
    Code:
    	printf("The value you input in ROMAN NUMERALS was: %s", LETTERS);
    	printf("The equivalent value in Arabic numbers is: %i", ANSWER);
    Consider printing some newlines (\n) there.

    BTW, in C++, standard practice is to use lowercase for variable and function names, or sometimes initial capitals (aVariable, TheClass) -- but not all capitals. That's usually reserved for constants. Your way is fine, but initially readers might be a little confused.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Oooookay. Some comments:
    (1) int main [with a return 0; at the end], instead of void main
    (2) all those global variables, some of which get hidden by identically named variables in main. So, for instance, the countM that SORT sees is not the same countM that main sees.
    (3) All these CAPITALIZED names; why?
    (4) COUNT and COUNTLESS do not change their parameters (a local copy is changed, but that is not returned), so none of the countLetter variables ever change.
    (5) Your readahead doesn't check the current character; CC, XC, and IC all have the same effect (take away an X (even if one doesn't exist!) and add an XC -- or it would, if COUNT and COUNTLESS were working).
    (6) You should set up a loop so that if RESTART returns true (say), then the loop continues, else it stops and you finish off in main.
    (7) I think you've got the "reading characters from a string and assigning them to a single char" bit down perfectly (except for index being a global variable).

    I suggest taking away the global variables and passing things in and returning them properly. If a value needs to be changed (such as in COUNT) return it. Pass index into the SORT and READLETTER2 functions, or better yet, just pass the string into SORT and let SORT do the loop.

  4. #4
    Registered User
    Join Date
    Nov 2007
    Posts
    12

    Smile

    Many thanks for both your suggestions... I shall use them wisely - you have been extremely helpful...

  5. #5
    Registered User
    Join Date
    Nov 2007
    Posts
    12

    Question Passing more than one variable through an array

    Hello again,

    I have had a go at piecing this back together into a more orderly structure and have learnt a few things from your advice...

    I am just a little bit confused about how to use these counts properly. I thought if I used them as a global variable it would work but aren't there too many of them to keep passing through functions and how would I go about doing that. I can't see how it would be done. I think I have corrected the index... passing? I mean to pass the counts between 'sort' 'readletter' and 'counter' functions... seems impossible to my small brain.

    Any advice would be taken humbly...
    Thanks


    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    char LETTERS[16];
    
    
    int total (int, int, int, int, int, int, int, int, int, int, int, int, int);
    int countless (int);
    int counter (char, int);
    int readletter2 (char, int);
    int count (int, int);
    void sort (char);				// converts the NUMERALS into counts
    void readkeyboard ();					// reads the string from the keyboard 
    void ask ()	;					// asks for input type
    int fork(int);						// choose (F)ile or (K)eyboard
    
    
    
    int total (int m, int d, int c, int l, int x, int v, int i, int cm, int cd, int xc, int xl, int ix, int iv)
    {
    	return (m*1000) + (d*500) + (c*100) + (1*50) + (x*10) + (v*5) + (i) + (cm*900) + (cd*400) + (xc*90) + (xl*40) + (ix*9) + (iv*4);
    }
    
    
    int countless (int a)
    {
    	a --;
    	return a;
    }
    
    int counter (char Tab[16], int i)  // TALLIES AND ERROR CHECKS THE DOUBLE NUMERAL COUNTS
    {	
    	switch (Tab[i])
    	{
    	case '\0':
    		break;
    	case 'D':
    		REP = 1; countless(countC); count(countCM, REP); break;
    	case 'M':
    		REP = 1; countless(countC); count(countCD, REP); break;
    	case 'C':
    		REP = 1; countless(countX); count(countXC, REP); break;	
    	case 'L':
    		REP = 1; countless(countX); count(countXL, REP); break;
    	case 'X':
    		REP = 1; countless(countI); count(countIX, REP); break;
    	case 'V':
    		REP = 1; countless(countI); count(countIV, REP); break;
    	default:
    		printf("You have input an invalid character");
    		RESTART ();
    	}
    	return i;
    }
    
    
    int readletter2 (char Tab[16], int i)		// READS THE SECOND THE SECOND NUMERAL AFTER THE PRIMARIES C, X and I AND PERFORMS TALL
    {	
    	i ++;	
    	counter (Tab[16], int i);
    	return i;
    }
    
    
    
    int count (int i, int rep)			// CHECKS AND TALLIES THE SINGLE NUMERAL COUNTS
    {
    	(i ++);
    	if (i > rep)
    	{
    		printf("You have input too many consecutive numerals");
    		RESTART();
    	}
    	return i;
    }
    
    
    char sort (char Tab[16])
    {
    	int i;
    	int REP;
    
    	for (i = 0; Tab[i] != '\0'; i++);
    
    		{	
    			switch (Tab[i]) 
    			{
    				case 'M':
    					REP = 4; count(countM, REP); break;
    				case 'D':
    					REP = 1; count(countD, REP); break;
    				case 'C':
    					REP = 3; count(countC, REP); readletter2(Tab[i], i); break;
    				case 'L':
    					REP = 1; count(countL, REP); break;
    				case 'X':
    					REP = 3; count(countX, REP); readletter2(Tab[i], i); break;
    				case 'V':
    					REP = 1; count(countV, REP); break;
    				case 'I':
    					REP = 3; count(countI, REP); readletter2(Tab[i], i); break;
    				default:
    					printf("You have input an invalid character"); RESTART ();
    			}
    		}
    }
    
    
    void readkeyboard (char Tab[16])			// FOR KEYBOARD MODE ASK FOR NUMERALS AND COPY INTO "LETTERS"
    {									//and change string to upper case	
    	int x;
    
    	printf("\n Please input your ROMAN NUMERALS from the keyboard: ");
    	scanf("%s", LETTERS);
    	for (x=0; x<strlen(LETTERS); ++x)
    	{
    		LETTERS[x] = toupper(LETTERS[x]);
    	}
    }
    
    
    void ask ()
    {
    	printf("\n Choose 1 for FILE input");
    	printf("\n Choose 2 for KEYBOARD input: ");
    }	
    
    int fork(int c)
    {
    	scanf("%i", &c)	
    		
    		while ((c <=0) || (c >=3));	
    	
    	if (c == 1)
    		printf("You have chosen one - file input");
    	else if (c == 2)
    	{
    		printf("You have chosen two - file input");	// FOR KEYBOARD MODE ASK FOR NUMERALS AND COPY INTO "LETTERS"
    		readkeyboard ();
    	}
    
    int main ()
    {			// DECLARE VARIABLES ETC...
    
    	int countM = countD = countC = countL = countX = countV = countI = countCM = countCD = countXC = countXL = countIX = countIV = 0;
    	int answer = 0;
    
    	// CHOOSE BETWEEN KEYBOARD & BATCH MODE
    
    	ask();
    	fork ();
    	sort (LETTERS);
    	answer = total(countM, countD, countC, countL, countX, countV, countI, countCM, countCD, countXC, countXL, countIX, countIV);
    
    	printf("The value you input in ROMAN NUMERALS was: %s", LETTERS);
    	printf("The equivalent value in Arabic numbers is: %i", answer);
    }

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    Code:
    counter (Tab[16], int i);
    When you pass variables to functions, you don't include types, and in this case, to pass an array, you use just the array's name without any square brackets. Using "Tab[16]" means that you're passing the 17th element in Tab to the function -- which, as well as being one character instead of an entire array, is also one past the end of the array.

    In other words, you probably want something like
    Code:
    counter(Tab, i);
    Code:
    int fork(int c)
    {
    	scanf("&#37;i", &c)	
    		
    		while ((c <=0) || (c >=3));
    Since that while loop doesn't have a matching do, it's an ordinary while and not a do-while loop. This means that if c <= 0 or c >= 3, the while loop will enter an infinite loop, because
    Code:
    while ((c <=0) || (c >=3));
    is the same as
    Code:
    while ((c <=0) || (c >=3)) {
    
    }
    I think you meant to use
    Code:
    int fork(int c)
    {
    	do
    
    	scanf("%i", &c)	
    		
    		while ((c <=0) || (c >=3));
    or, more readably,
    Code:
    int fork(int c)
    {
    	do {
    		scanf("%i", &c)	
    	} while ((c <=0) || (c >=3));
    BTW, fork() is the same of a standard POSIX function, so consider a different name for your function.

    Code:
    	for (x=0; x<strlen(LETTERS); ++x)
    	{
    		LETTERS[x] = toupper(LETTERS[x]);
    	}
    strlen() is expensive in terms of time to compute, so if you save its value your code will be much more efficient:
    Code:
     int len = strlen(LETTERS);
    	for (x=0; x<len; ++x)
    	{
    		LETTERS[x] = toupper(LETTERS[x]);
    	}
    (I like to use variables of type size_t to store the return value of strlen() and loops that depend on this value, but int should be sufficient in most cases.)

    Code:
    (i ++);
    Those parentheses are unnecessary, but they don't do any harm.

    Code:
    int countM = countD = countC = countL = countX = countV = countI\
    = countCM = countCD = countXC = countXL = countIX = countIV = 0;
    You cannot do that when you're declaring variables. You can do it after the variables are declared, but not there. In addition, several other functions use these variables (which are local to main()) -- in order for this to work, you'll need to declare these variables as global (bad idea), or pass them on to those functions that need them, such as sort() (semi-okay idea). Best of all, because there are so many variables, you might want to do something like this.

    Code:
    #define COUNT_M 0
    #define COUNT_D 1
    #define COUNT_C 2
    /* ... */
    
    int count[13];
    or, perhaps
    Code:
    enum {
        COUNT_M
        COUNT_D
        COUNT_C,
        /* ... */
    };
    
    int count[13];
    which is the same thing, except the compiler does the counting for you; and then you'd use
    Code:
    count[COUNT_C]
    instead of countC. Or something like that. Imagine what the declaration of total() would look like then!
    Code:
    int total(int count[13]) {
    So simple . . . .

    Code:
    int fork(int c)
    {
    	scanf("%i", &c)
    Why are you clobbering a parameter like that? I think this would do:
    Code:
    int fork(void)
    {
    	int c;
    	scanf("%i", &c)
    There are also a few other points in my previous post that you haven't implemented yet -- consider re-reading it.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    Registered User
    Join Date
    Nov 2007
    Posts
    12

    Question

    I have put it together and think it should now work, however I am getting linking errors that I can't understand... they are:

    1>Linking...
    1>Code.obj : error LNK2019: unresolved external symbol "void __cdecl restart(void)" (?restart@@YAXXZ) referenced in function "int __cdecl counter(char * const,int)" (?counter@@YAHQADH@Z)
    1>Code.obj : error LNK2019: unresolved external symbol "int __cdecl readletter2(char,int)" (?readletter2@@YAHDH@Z) referenced in function "void __cdecl sort(char * const)" (?sort@@YAXQAD@Z)
    1>Code.obj : error LNK2019: unresolved external symbol "void __cdecl readkeyboard(void)" (?readkeyboard@@YAXXZ) referenced in function "void __cdecl choice(void)" (?choice@@YAXXZ)
    1>Code.obj : error LNK2019: unresolved external symbol "int __cdecl total(int)" (?total@@YAHH@Z) referenced in function _main
    1>\\regent\user\ELT\rjt31\My Documents\Visual Studio 2005\Projects\Mini Project\Debug\Mini Project.exe : fatal error LNK1120: 4 unresolved externals


    can you help???

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    enum count {CountM, CountD, CountC, CountL, CountX, CountV, CountI, CountCM, CountCD, CountXC, CountXL, CountIX, CountIV};
    
    int count [13];
    
    char LETTERS[16];
    
    void restart ();	
    int total (int);
    int countless (int);
    int counter (char, int);
    int readletter2 (char, int);
    int COUNT (int, int);
    void sort (char);				// converts the NUMERALS into counts
    void readkeyboard ();					// reads the string from the keyboard 
    void ask ()	;					// asks for input type
    void choice();						// choose between file or keyboard
    
    
    void RESTART ()			// RESTARTS THE WHOLE PROGRAMME
    {
    	int yn;
    	printf("Do you wish to try again? Enter Y to continue \n(else enter anything else to quit): ");
    	scanf("%i", &yn);
    
    	if(tolower(yn) == 'y')
    	{
    		ask (); 
    		choice();
    	}
    }
    
    int total (int count[13])
    {
    	return ((count[0]*1000) + (count[1]*500) + (count[2]*100) + (count[3]*50) + (count[4]*10) 
    		+ (count[5]*5) + (count[6]) + (count[7]*900) + (count[8]*400) + (count[9]*90) + (count[10]*40) 
    		+ (count[11]*9) + (count[12]*4));
    }
    
    int countless (int a)
    {
    	a --;
    	return a;
    }
    
    int counter (char Tab[16], int i)  // TALLIES AND ERROR CHECKS THE DOUBLE NUMERAL COUNTS
    {	
    	int REP;
    	switch (Tab[i])
    	{
    	case '\0':
    		break;
    	case 'M':
    		REP = 1; countless(count[CountC]); COUNT(count[CountCM], REP); break;
    	case 'D':
    		REP = 1; countless(count[CountC]); COUNT(count[CountCD], REP); break;
    	case 'C':
    		REP = 1; countless(count[CountX]); COUNT(count[CountXC], REP); break;	
    	case 'L':
    		REP = 1; countless(count[CountX]); COUNT(count[CountXL], REP); break;
    	case 'X':
    		REP = 1; countless(count[CountI]); COUNT(count[CountIX], REP); break;
    	case 'V':
    		REP = 1; countless(count[CountI]); COUNT(count[CountIV], REP); break;
    	default:
    		printf("You have input an invalid character");
    		restart ();
    	}
    	return i;
    }
    
    
    int readletter2 (char Tab[16], int i)		// READS THE SECOND THE SECOND NUMERAL AFTER THE PRIMARIES C, X and I AND PERFORMS TALL
    {	
    	i ++;	
    	counter (Tab, i);
    	return i;
    }
    
    int COUNT (int i, int rep)			// CHECKS AND TALLIES THE SINGLE NUMERAL COUNTS
    {
    	i ++;
    	if (i > rep)
    	{
    		printf("You have input too many consecutive numerals");
    		restart();
    	}
    	return i;
    }
    
    void sort (char Tab[])
    {
    	int i;
    	int REP;
    
    	for (i = 0; Tab[i] != '\0'; i++);
    
    		{	
    			switch (Tab[i]) 
    			{
    				case 'M':
    					REP = 4; COUNT(count[CountM], REP); break;
    				case 'D':
    					REP = 1; COUNT(count[CountD], REP); break;
    				case 'C':
    					REP = 3; COUNT(count[CountC], REP); readletter2(Tab[i], i); break;
    				case 'L':
    					REP = 1; COUNT(count[CountL], REP); break;
    				case 'X':
    					REP = 3; COUNT(count[CountX], REP); readletter2(Tab[i], i); break;
    				case 'V':
    					REP = 1; COUNT(count[CountV], REP); break;
    				case 'I':
    					REP = 3; COUNT(count[CountI], REP); readletter2(Tab[i], i); break;
    				default:
    					printf("You have input an invalid character"); 
    					restart ();
    			}
    		}		
    }
    
    void readkeyboard (char Tab[16])			// FOR KEYBOARD MODE ASK FOR NUMERALS AND COPY INTO "LETTERS"
    {									//and change string to upper case	
    	int x;
    	int len = strlen(LETTERS);
    
    	printf("\n Please input your ROMAN NUMERALS from the keyboard: ");
    	scanf("%s", LETTERS);
    	for (x=0; x<len; ++x)
    	{
    		LETTERS[x] = toupper(LETTERS[x]);
    	}
    }
    
    void ask ()
    {
    	printf("\n Choose 1 for FILE input");
    	printf("\n Choose 2 for KEYBOARD input: ");
    }	
    
    void choice(void)
    {
    	int c;
    	do
    	{
    		scanf("%i", &c);
    	}		
    	while ((c <=0) || (c >=3));	
    
    	if (c == 1)
    		printf("You have chosen one - file input");
    	else if (c == 2)
    	{
    		printf("You have chosen two - file input");	// FOR KEYBOARD MODE ASK FOR NUMERALS AND COPY INTO "LETTERS"
    		readkeyboard ();
    	}
    }
    
    int main ()
    {			// DECLARE VARIABLES ETC...
    	int answer = 0;
    
    	// CHOOSE BETWEEN KEYBOARD & BATCH MODE
    
    	ask();
    	choice();
    	sort (LETTERS);
    	answer = total(count[13]);
    
    	printf("\n The value you input in ROMAN NUMERALS was: %s", LETTERS);
    	printf("\n The equivalent value in Arabic numbers is: %i", answer);
    }

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    RESTART is different from restart (and you should really change your name to "restart" for the actual function implementation, rather than the call to restart to RESTART, as upper case names are commonly used for macro names, not function names).

    C++ is picky about function prototypes and the declaration of the function, including arguments:
    Code:
    int readletter2 (char, int);
    ...
    int readletter2 (char Tab[16], int i);
    That is two different functions - one is probably more right than the other. The compiler thinks you are using the first one, but you define the second one.

    And similar problem with readkeyboard and total.
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,457
    Because your function declarations are wrong:

    Code:
    void restart ();	/* Your actual function name is RESTART, which is not the same as restart. */
    int total (int); /* Should be int total(int[13]); */
    int readletter2 (char, int); /* Should be int readletter2(char[16], int); */
    void readkeyboard (); /* Should be void readkeyboard(char[16]); */
    You must make sure your definitions of your functions and declarations match, or you'll get a compile or linking error.

  10. #10
    Registered User
    Join Date
    Nov 2007
    Posts
    12

    Unhappy

    I think I was a bit out of my league with all those functions... I have reduced them down and put a lot more of the programme into main.

    It all works but I keep getting the default message from the switch whenever I input a string no matter what - it doesn't sort though properly . I can't understand how it is missing the numerals in the string...

    Please please help me...

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    enum count {CountM, CountD, CountC, CountL, CountX, CountV, CountI, CountCM, CountCD, CountXC, CountXL, CountIX, CountIV};
    
    char LETTERS[16];
    
    
    void initialise (char []);
    void initialize (int []);
    void restart ();	
    void readkeyboard();					// reads the string from the keyboard 
    void ask ()	;					// asks for input type
    void choice();						// choose between file or keyboard
    
    
    void initialize (int tab[])
    {
    	int i;
    	for (i=0; i<=15; ++i)
    		tab[i] = 0;
    }
    
    void initialise (char tab[])
    {
    	int i;
    	for (i=0; i<=15; ++i)
    		tab[i] = 0;
    }
    
    
    void restart ()			// RESTARTS THE WHOLE PROGRAMME
    {
    	int yn;
    	printf("Do you wish to try again? Enter Y to continue \n(else enter anything else to quit): ");
    	scanf("%i", &yn);
    
    	if(tolower(yn) == 'y')
    	{
    		ask (); 
    		choice();
    	}
    }
    
    
    void readkeyboard ()			// FOR KEYBOARD MODE ASK FOR NUMERALS AND COPY INTO "LETTERS"
    {									//and change string to upper case	
    	int x;
    	int len = strlen(LETTERS);
    
    	printf("\n Please input your ROMAN NUMERALS from the keyboard: ");
    	scanf("%s", LETTERS);
    	for (x=0; x<len; ++x)
    	{
    		LETTERS[x] = toupper(LETTERS[x]);
    	}
    }
    
    void ask ()
    {
    	printf("\n Choose 1 for FILE input");
    	printf("\n Choose 2 for KEYBOARD input: ");
    }	
    
    void choice(void)
    {
    	int c;
    	do
    	{
    		scanf("%i", &c);
    	}		
    	while ((c <=0) || (c >=3));	
    
    	if (c == 1)
    		printf("You have chosen one - file input");
    	else if (c == 2)
    	{
    		printf("You have chosen two - file input");	// FOR KEYBOARD MODE ASK FOR NUMERALS AND COPY INTO "LETTERS"
    		readkeyboard ();
    	}
    }
    
    int main ()
    {			// DECLARE VARIABLES ETC...
    	int answer = 0;
    	int total;
    	int i;
    	int REP;
    	int count [13];
    
    	// CHOOSE BETWEEN KEYBOARD & BATCH MODE
    
    	initialise (LETTERS);
    	initialize (count);
    	ask();
    	choice();
    	 
    	
    	for (i = 0; LETTERS[i] != '\0'; i++);
    
    		{	
    			switch (LETTERS[i]) 
    			{
    				case 'M':
    					REP = 4; 
    					++ count[CountM]; 
    					if (count[CountM] > REP)
    					{
    						printf("You have input too many consecutive numerals");
    						restart();
    					}
    					break;
    
    				case 'D':
    					REP = 1; 
    					++ count[CountD]; 
    					if (count[CountD] > REP)	
    					{
    						printf("You have input too many consecutive numerals");
    						restart();
    					}					
    					break;
    
    				case 'C':
    					REP = 3; 
    					++ count[CountC];
    					if (count[CountC] > REP)	
    					{
    						printf("You have input too many consecutive numerals");
    						restart();
    					}	
    
    					i ++;
    					REP = 1;
    
    					switch (LETTERS[i])
    					{		
    					case '\0':
    						break;
    					case 'M':
    						-- count[CountC]; ++ count[CountCM];
    
    						if (count[CountCM] > REP)	
    						{
    							printf("You have input too many consecutive numerals");
    							restart();
    						}			
    						break;
    					
    					case 'D':
    						-- count[CountC]; ++ count[CountCD];
    						if (count[CountCD] > REP)	
    					{
    						printf("You have input too many consecutive numerals");
    						restart();
    					}	
    						break;
    					}
    					break;
    
    				case 'L':
    					REP = 1; 
    					++ count[CountL];
    					if (count[CountL] > REP)	
    					{
    						printf("You have input too many consecutive numerals");
    						restart();
    					}	
    					break;
    
    				case 'X':
    					REP = 3; 
    					++count[CountX];
    					if (count[CountX] > REP)	
    					{
    						printf("You have input too many consecutive numerals");
    						restart();
    					}	
    
    					i ++;
    					REP = 1;
    
    					switch (LETTERS[i])
    					{		
    					case '\0':
    						break;
    					case 'C':
    						-- count[CountX]; ++ count[CountXC];
    
    						if (count[CountXC] > REP)	
    						{
    							printf("You have input too many consecutive numerals");
    							restart();
    						}			
    						break;
    					
    					case 'L':
    						-- count[CountX]; ++ count[CountXL];
    						if (count[CountXL] > REP)	
    					{
    						printf("You have input too many consecutive numerals");
    						restart();
    					}	
    						break;
    					}
    					break;
    
    				case 'V':
    					REP = 1; 
    					++ count[CountV];
    					if (count[CountV] > REP)	
    					{
    						printf("You have input too many consecutive numerals");
    						restart();
    					}	
    					break;
    
    				case 'I':
    					REP = 3; 
    					++ count[CountI];
    					if (count[CountI] > REP)	
    					{
    						printf("You have input too many consecutive numerals");
    						restart();
    					}	
    
    					i ++;
    					REP = 1;
    
    					switch (LETTERS[i])
    					{		
    					case '\0':
    						break;
    
    					case 'X':
    						-- count[CountI]; ++ count[CountIX];
    
    						if (count[CountIX] > REP)	
    						{
    							printf("You have input too many consecutive numerals");
    							restart();
    						}			
    						break;
    					
    					case 'D':
    						-- count[CountI]; ++ count[CountIV];
    						if (count[CountIV] > REP)	
    					{
    						printf("You have input too many consecutive numerals");
    						restart();
    					}	
    						break;
    					}
    					break;
    
    				default:
    					printf("You have input an invalid character"); 
    					restart ();
    			}
    		}	
    
    	total = ((count[CountM]*1000) + (count[CountD]*500) + (count[CountC]*100) + (count[CountL]*50) + (count[CountX]*10)
    		+ (count[CountV]*5) + (count[CountI]) + (count[CountCM]*900) + (count[CountCD]*400) + (count[CountXC]*90) + (count[CountXL]*40) 
    		+ (count[CountIX]*9) + (count[CountIV]*4));
    
    	printf("\n The value you input in ROMAN NUMERALS was: %s", LETTERS);
    	printf("\n The equivalent value in Arabic numbers is: %i", total);
    }

  11. #11
    Registered User
    Join Date
    Nov 2007
    Posts
    12

    Unhappy

    roman numerals in the string - sorry not numbers... please help

  12. #12
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,457
    You're mixing C and C++. Which one do you want?
    Also, avoid global variables and just use ZeroMemory or memset to initialize your variables or just do
    Code:
    char somearray[10] = {0};

  13. #13
    Registered User
    Join Date
    Nov 2007
    Posts
    12
    I want C, but posted in the wrong forum...

  14. #14
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,457
    AFAIK, overloading functions is not supported in C. I'm surprised the compiler will even allow that.

  15. #15
    Registered User
    Join Date
    Nov 2007
    Posts
    12
    So should I try and get rid of all functions? The reason I started using functions was to make it neater but also to allow me to start again if there was an error detected. Only in my first term of programming so not really 100&#37; about anything at the moment...

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

Similar Threads

  1. Assigning a non null-terminated string
    By BattlePanic in forum C Programming
    Replies: 7
    Last Post: 05-04-2008, 10:02 PM
  2. Replies: 9
    Last Post: 11-23-2007, 11:28 AM
  3. assigning a string to a variable
    By xp5 in forum C Programming
    Replies: 12
    Last Post: 08-30-2007, 01:13 AM
  4. Assigning a String object to char*
    By The Dog in forum C++ Programming
    Replies: 13
    Last Post: 07-14-2002, 04:41 PM
  5. Again Character Count, Word Count and String Search
    By client in forum C Programming
    Replies: 2
    Last Post: 05-09-2002, 11:40 AM

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