d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Seeking Wisdom For My First Project! Help Please!
123Next
Add Reply New Topic New Poll
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Sep 10 2012 01:56pm
SKIP TO THE BOTTOM IF YOU JUST WANT TO HELP ME WITH SOMETHING PLEASE!!


Project details:

Quote
CS 2250 Project 1 Fall 2012
Your first project is to write a program which reads from standard input a series of lines of
Latin nouns and adjectives and to output to the screen their declination.
In many languages, nouns (and adjectives) are declined into a variety of forms [called ”cases”]
to show their function in the sentence. In Latin, there are 5 cases: nominative [subject],
genitive [possession], dative [indirect object], accusative [direct object], and ablative [adverbial
usages] with 2 numbers: singular and plural. In English, only pronouns have any cases;
for nouns and adjectives, we only distinguish number.
The input will consist of lines with 2 blank-separated forms of a noun or an adjective: the
nominative singular and the genitive singular. The final line will contain the word ”QUIT”
(all in capitals).

If the genitive ends in ”ae”, the word in the in First Declination. The stem is found by
removing the ”ae” from the genitive. The cases are formed by adding the following endings
to the stem

Singular Plural
Nom. [given] ae
Gen. ae arum
Dat. ae is
Acc. am as
Abl. a is

If the genitive ends in ”i”, the word in the in Second Declination. The stem is found by
removing the ”i” from the genitive. There are 2 possibilities: nominative ends in ”um” and
nominative end in ”us” or ”r”. The cases are formed by adding the following endings to the
stem:

-us or -r Words -um Words
Singular Plural Singular Plural
Nom. [given] i [given] a
Gen. i orum i orum
Dat. o is o is
Acc. um os um a
Abl. o is o is



basically he gives us an input file that might look like

xxxx xxxx
yyyy yyyy
zzzz zzzz
QUIT


he will compile our code and input the file as such
g++ project.cpp < inputs

so the idea is that if he gives us, for example, the line

Code
vir viri


The code needs to do this:

read the line into a string. It should recognize the first word as the NOM. SINGULAR and the second as the GEN. SINGULAR

from there, we need to achieve the STEM. We do this by taking the GEN SING and removing the part at the end. In this case, viri, the 'i' is the end, so we remove it and the stem becomes 'vir'.

It should be noted there are 3 possible cases for this.

The GEN. SING. ends in either 'ae', 'us OR r' & 'um'

Once we figure out which, we list out the 5 latin forms of the word.


For the vir example, it would be

vir viri
viri virorum
viro viris
virum viros
viro viris


------------------------------------------------------------------------------------------------------------------------------------------------------

Now, that aside, I need some help doing the very first task. I can probably figure out the string manipulation stuff, but I need a good way to read the first line of the input document, separate the two words into two different strings? Then be able to mess around with them. I never really learned how to do this in 1250 and the prof didn't really tell us how to do it either. Basically, the 2nd word is the one I need the most I think.


Can someone shed some light on how to do this? (The words will most likely be separated with a single space)

I think what I want to do is:

Use a while loop to read line by the line the document.

Put the 2 words of a line into 2 different strings. Use the 2nd string to check to see if the word ends in 'ae' or 'i'

If it ends in i, it also checks string 1 to see if it ends in 'us' or 'r' or to see if it ends in 'um'

Once we get through all of these statements, we will take the word contained in string2, delete the ending characters (i or ae) and then copy that into a new string called STEM.

Depending on what is true, I will then (probably) perform some minor string manipulations and print out each line

ex:

NOM [string1] [STEM+i]
GEN [string2] [STEM+orum]
DAT [stem + o] [stem + is]
ACC [stem + um] [stem + os]
ABL [stem + o] [stem + is]

More questions:

Can I use the same variable names for the loop?

Like if I do

string term1,term2,stem;

If I put a word into term1 and term 2 and find stem, print them out, then go to line 2....

will the compiler like, add the new line terms into term1 and term2 or will it be smart enough to clean them out?

Poorly worded on my part but basically wondering how this would all work.

This post was edited by Eep on Sep 10 2012 02:19pm
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Sep 10 2012 02:40pm
Quote
Once we get through all of these statements, we will take the word contained in string2, delete the ending characters (i or ae) and then copy that into a new string called STEM.


Don't quote me for competence on a lot of what I said. I know the way I spoke it out was wrong. Like here, I wouldn't delete then copy, I would copy then delete ~_~


sorry if my explanation sucks

edit: Think a friend solved one of my questions. Now I just need to figure out how to read a line with 2 words separated by a space and put each into a different string. Then I am G2G!

edit 2: Just use MOAR STRING.

Might be able to do this on my own now.

This post was edited by Eep on Sep 10 2012 03:08pm
Member
Posts: 2,673
Joined: Jun 23 2006
Gold: 300.00
Sep 10 2012 05:34pm
I bet in the time it took you to write all of this, you could have finished the project with time left over to jerk it for a bit.
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Sep 10 2012 07:41pm
Quote (phintastic @ Sep 10 2012 06:34pm)
I bet in the time it took you to write all of this, you could have finished the project with time left over to jerk it for a bit.


maybe. Writing it down actually helped me think it through better actually.

Anyways, I still need some help with the loop. I need to the loop to stop when the line reads QUIT

should I just do a

while (cin >> tempStr)
if (tempStr = "QUIT")
{
break;
}


??
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Sep 10 2012 09:52pm
Quote (Eep @ Sep 10 2012 09:41pm)
maybe. Writing it down actually helped me think it through better actually.

Anyways, I still need some help with the loop. I need to the loop to stop when the line reads QUIT

should I just do a

while (cin >> tempStr)
if (tempStr = "QUIT")
{
break;
}


??



pretty much.

im not sure how c++ handles strings but fgets reads x number of bytes until x is met or a '\n' character is found.

also make sure to lowercase all your read in input else any typos might cause errors. a simple function i made was this.

Code
void alphanum2upper(char *str)
{
   int i = strlen(str);
   while (i-->0)
   {
       if (*str >= (int)'a' && *str <= (int)'z')
       {
           *str-=32;
       }
   str++;
   }
}


takes a pointer to a CSTRING and minuses 32 from it causing the lower case letters to become uppercase. to reverse that and turn upper to lower you can add +32.

the c++ equivilent would to pass a string and minus or add 32 to each element (looping through it and checking if it falls withing a-z) and then returning a string. the function call should look something like

Code
some_string = alphanum2upper(some_string);


dont quote me on that though

should be easy to rewrite using string though and avoid pointers.

as for separating the output into 2 strings you can use the strtok function to separate strings by a single character.

Code
int main()
{
   char userInput[81];
   char *functionOutput[80];
   int i = 0;


   printf("Enter a string to test the split function\n");
   fgets(userInput, sizeof(userInput), stdin);

   split(userInput, ".", functionOutput);int i

   while(functionOutput[i] != '\0')
   {
       printf("%s\n", functionOutput[i]);
       i++;
   }

   getchar();
   return 0;

}



void split(char *input, char *dilimeter, char **output)
{
   int i = 0;

   output[0] = strtok(input, dilimeter);

   while(output[i] != NULL)
   {
       i++;
       output[i] = strtok(NULL, dilimeter);
   }

   output[i + 1] = '\0';
}


quick example i had on hand from a previous project.

of course all this is in C using C functions im sure c++ has some built in splitting functions you can call by stringname.split(' '); or something.

This post was edited by AbDuCt on Sep 10 2012 09:54pm
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Sep 13 2012 12:23am
Need help again.

Trying to get my first (and most integral) function done for my project.

I am making a function which splits my string.

My idea was to do this:

Read in a line from the user (for this project, it will be two words separated by a space) this we will call STRING INPUT for now.

Next, I set some variables, lets say x = length of the string and y = position of the whitespace

then, I WANTED to use the string.copy function to copy from the first element of INPUT up until y-1, and put it into a new string


My TEST code was this:

Code
int main() {
string x = "Hello World";
size_t pos, y;

string string1, string2;

pos =int(x.find(" "));

y = int(x.length());

cout << pos << endl;

x.copy(string1,pos-1,0);
x.copy(string2,y-pos,pos+1);

cout << string1;
cout << string2;


(yes yes I am missing the bottom part with return 0 not a big deal)


and I keep getting errors, specifically that I am calling the wrong function? (I have included <string> just fyi)

I keep checking around and it seems that string.copy does NOT work the way it was taught to me // the way I THOUGHT it would work.

Can anyone help me out?

This post was edited by Eep on Sep 13 2012 12:26am
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Sep 13 2012 02:11am
god I keep changing my mind with this thing...it is so annoying.
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Sep 13 2012 03:03am
Okay so I have a new problem now, nevermind the last one I had



New problem:

The list of inputs going into our program is like this:


xxx yyy
xxx yyy
xxx yyy
xxx yyy
xxx yyy
QUIT


what I need to do:

If (yyy ends in "ae")
do some stuff

else if (xxx ends in "r or us")
do some other stuff
else do something completely different.

My big problem is that initially I wrongly assumed that I could read in an input file 1 line at a time and do stuff then it would automatically go to the next line and do stuff until it reached QUIT then it would stop.


I cannot figure out how to get my program to read the input file one line at a time and do stuff. So do I really have to just read in this giant ass document as 1 giant string and then painstakingly pull each piece apart then work from there??

Is there no way to work 1 line at a time from the document? Maybe I could use fstream or something? Can someone offer me a suggestion?
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Sep 13 2012 07:32am
use fgets()

as i said it reads x number of bytes or until it reaches a '\n' character aka a new line

or use getline() which essentially does the same thing but uses c++ streams

Code
ifstream stream("filename.txt");
string dummyLine;
while (!stream.eof)  //or you can just use while(stream) which is better then !stream.eof
getline(stream, dummyLine);
  ...


man im slow today just woke up

here is a better varriation of the code

Code
ifstream stream("filename.txt");
string dummyLine;
while (getline(stream, dummyLine))
{
  ...
}


the loop is only entered if reading from stream is OK. if not it wont try to read from the stream.

edit

as for splitting your text if you get that method working i suggest changing string1/2 into an array of strings to clean it up.

as for checking the endings of the words first thing that comes to mind is vb6 mid/right/left functions like.

but in your case id look into c++ substring functions

in C you can do this

Code
#include <string.h>

main(){
 const char* from = "12345678";
 char *to;
 to=strndup(from+2, 5);
 free(to);
}


in c++ you can use the string::substr method which is problally the answer to your string::copy problem

http://www.cplusplus.com/reference/string/string/substr/

Code
// string::substr
#include <iostream>
#include <string>
using namespace std;

int main ()
{
 string str="We think in generalities, but we live in details.";
                            // quoting Alfred N. Whitehead
 string str2, str3;
 size_t pos;

 str2 = str.substr (12,12); // "generalities"

 pos = str.find("live");    // position of "live" in str
 str3 = str.substr (pos);   // get from "live" to the end

 cout << str2 << ' ' << str3 << endl;

 return 0;
}


essentially you

Code
string x = "xxx yyy"
int len = 0, pos = 0;
string x2[2];

pos = x.find(" "); //splits the words
x2[0] = x.substr(0, pos - 1);
x2[1] = x.substr(pos);

len = x2[0].length();
if(x2[0].substr(length - 2) == "ae")
{
  ...
}


hopefully you get the idea

edit:: if you dont specify the length substr is susposed to read as the second argument it copys everything until the end of the string.

This post was edited by AbDuCt on Sep 13 2012 07:52am
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Sep 13 2012 01:34pm
so let's suppose I can't use fstream. (Sorry it was late and a bad idea on my part)


What IS going to happen is this:

The professor, when he grades, is going to input a text containing lines (like I posted above) as he compiles

!g++ % && a.out < inputs


So basically its like someone is turning on my program and entering lines of data one at a time.


I need someone to CLARIFY for me what my options are at this point:

1: Is the only way to read in those lines by doing it as one giant string then trying to pick it apart??? If so, HOW DO I DO THIS?

2: Is there a way for me to have the program read 1 line, do stuff with it, print it, THEN go to the next line and do something similar, etc?


I am just beyond stumped right now.
Go Back To Programming & Development Topic List
123Next
Add Reply New Topic New Poll