1. Not finding help here? Sign up for a free 30min tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C newbie on strings and arrays (Urgent, due monday)

  1. Oct 29, 2008 #1
    I am required to use getline() and sscanf() somewhere in my function to read standard input and store it into arrays.
    I have input like this:

    10/10/08 12:00
    A1:2.31:1:P
    2B:1.98:2:g
    2b:1.82:3:b

    the first line is the time, which i used strcpy to copy it to an array called time[]
    the second to fourth lines i am required to check that the first two characters before the colon are between a-z, A-Z, 0-9, plus i need to store it in a two dimensional array which i have no idea how. The characters after the first colon need to be to 2 decimal places only and positive, the characters after the second colon need to be positive, and the character after the third colon can only be chosen from a few specific characters.
    So far i have this in my function:

    int c;
    int a=0;
    while((getline(line, NUM))>0)
    if (line[2]=='/')
    strcpy(time, line);
    else strcpy(purchaseline, line);
    /*don't know how to filter out the characters that don't meet the requirements. maybe use a for loop? maybe i could declare 5 new int/chars so that sscanf can store the input there, and then i could test the condition of the values stored in these int/chars and choose to store them in the actual name, price, quantity, taxtype arrays?*/
    sscanf(purchaseline, "%c%c:%0.2lf:%d:%c", name+a, name+a+1, price+a, quantity+a, taxtype+a);

    /*name, price, quantity, and purchaseline are all arrays*/

    this is basically the boiled down version of the assignment i think
    if anyone has time to read more about the assignment, the link is here:
    http://www.megaupload.com/?d=D9BDOK1N
     
    Last edited: Oct 29, 2008
  2. jcsd
  3. Oct 29, 2008 #2

    mgb_phys

    User Avatar
    Science Advisor
    Homework Helper

    You need to store what in a 2d array?
    3d arrays aren't directly part of 'c' - you can either make an array of arrays, or if you know how many elements are on each line you can make a struct to hold these values and then make an array of these structs. Or you can store separate 1d arrays for each element in the line.

    To find out if a character is in a range you can either compare the character values directly to the values A-Z or you can see the isalpha,isnum and isalphanum() functions.

    Your sscanf line is completely wrong. You might want to find an example of scanf() on the net.

    hint - put your code in CODE tags - it makes it much easier to read.
    Code (Text):
    int a
     
  4. Oct 29, 2008 #3
    thanks for the quick reply

    i am given an array called name[NUM][2]
    for a given input line, I am to store the first two letters, eg. A1, such that

    Code (Text):

    name[0][0]='A';
    name[0][1]='1';
     
    and i am also not sure what is wrong with my sscanf. i was given the following example in class:

    Code (Text):

    char c;
    int i;
    double db;
    char s[80], outstring[80],
    *instring=“a 100 -1.23 This is a sample data”;
    sscanf(instring,“%c%d%lf%s”, &c, &i, &db, s);
    //Then c=‘a’, i=100, db=-1.23, s=“This”
     
    however, i made some changes to it just now and now it looks like this:

    Code (Text):

     int c;
     int a=0,b=0;
     char name1;
     char name2;
     double price1=0;
     unsigned int quantity=0;
     char taxtype;


     while((getline(line, NUM))>0){
        if (line[2]=='/')
            strcpy(time, line);
        else strcpy(purchaseline, line);
     }
    sscanf(purchaseline, "%c%c:%0.2lf:%d:%c", &name1, &name2, &price1, &quantity, &taxtype);

     if ((name1>='a'&& name1<='z')||(name1>='A'&& name1<='Z')||(name1>='0'&& name1<='9')){
        if ((name2>='a'&& name2<='z')||(name2>='A'&& name2<='Z')||(name2>='0'&& name2<='9')){
            if (price1>0){
                name[a][0]=name1;
                name[a][1]=name2;
                price[a]=price1;
                if (taxtype=='g' || taxtype=='G')
                    tax_type[a++]=taxtype;
                else if (taxtype=='p' || taxtype=='P')
                    tax_type[a++]=taxtype;
                else if (taxtype=='b' || taxtype=='B')
                    tax_type[a++]=taxtype;
                else
                    tax_type[a++]='N';
            }
        }
     }
     
     
  5. Oct 29, 2008 #4

    mgb_phys

    User Avatar
    Science Advisor
    Homework Helper

    Mostly the right idea:

    You are looping over all the input lines but only processing the last one after the loop exits.
    You need to put the parsing code inside the loop inplace of the secondstring copy.
    Or better, put it in a function that takes a string as the input and call it from inside the loop.

    ps. You haven't defined time or purchase line.
    pps. time isn't a good name - there is a library call called time() that returns the time!
    It doesn't matter to your code butwill confuse people.
     
  6. Oct 29, 2008 #5
    sorry, i have no idea what you meant by

    "You need to put the parsing code inside the loop inplace of the secondstring copy.
    Or better, put it in a function that takes a string as the input and call it from inside the loop."

    i put the huge chunk from sscanf onwards inside the while loop. and time and purchaseline were also given arrays. they are declared as static arrays along with name, price, quantity, etc.
     
  7. Oct 29, 2008 #6

    mgb_phys

    User Avatar
    Science Advisor
    Homework Helper

    What you are doing is

    1, read line
    2, copy line into purchaseline, overwriting previous purchase line
    3, repeat from 1
    4, When all lines done split purchaseline (note this is just the last purchaseline)

    What you meant to do is
    1, read line
    2, copy line into purchaseline, split purchaseline
    3, repeat from 1
     
  8. Oct 29, 2008 #7
    does this look good now? this is my entire function

    Code (Text):

    void purchase(void)
    {
     int c;
     int a=0,b=0;
     char name1;
     char name2;
     double price1=0;
     unsigned int quantity=0;
     char taxtype;


     while((getline(line, NUM))>0){
        if (line[2]=='/')
            strcpy(time, line);
        else strcpy(purchaseline, line);

     sscanf(purchaseline, "%c%c:%0.2lf:%d:%c", &name1, &name2, &price1, &quantity, &taxtype);

     if ((name1>='a'&& name1<='z')||(name1>='A'&& name1<='Z')||(name1>='0'&& name1<='9')){
        if ((name2>='a'&& name2<='z')||(name2>='A'&& name2<='Z')||(name2>='0'&& name2<='9')){
            if (price1>0){
                name[a][0]=name1;
                name[a][1]=name2;
                price[a]=price1;
                if (taxtype=='g' || taxtype=='G')
                    tax_type[a++]=taxtype;
                else if (taxtype=='p' || taxtype=='P')
                    tax_type[a++]=taxtype;
                else if (taxtype=='b' || taxtype=='B')
                    tax_type[a++]=taxtype;
                else
                    tax_type[a++]='N';
            }
        }
     }

     }
    }
     
    but when i run my program, this function for some reason doesn't terminate. I know this because i have a couple other functions as well. If i have purchase run before the other functions, the other functions are never executed.

    also, how do i enter standard input? i am told to use a unix command like:

    ./receipt < input.txt

    but I am using an IDE called Codeblocks, so I have no idea how to enter input to check my program.
     
  9. Oct 29, 2008 #8

    mgb_phys

    User Avatar
    Science Advisor
    Homework Helper

    Looks good, you could print the line read by getline immediately after the while line to check what is read.
    Either in codeblocks there will be an option to set commandline arguements.
    Or you can find where it puts the output executable and from the command line run the above command.
    Codeblocks runs on lots of platforms- what OS are you using?

    ps. getline() is gcc addition to the language, the more standard way is to use fgets(line, NUM, stdin)
    getline() can expand the string memory if the line is too long, but that isn't a problem here.
     
    Last edited: Oct 29, 2008
  10. Oct 30, 2008 #9
    mmm, i don't know how to do the commandline arguments and such, so i just tested my program by manually inputting the data and then using EOF to end it.
    My OS is Vista.
    for the program, i am supposed to make sure the standard input of price[] only has 2 decimal places and is positive. how do i do this?
    I tried using

    Code (Text):

    if (price>0.01 && (100*price - (int)100*price)==0)
        then blah blah blah
     
    but then i know i can't compare the double value 100*price with and integer
     
  11. Oct 30, 2008 #10

    mgb_phys

    User Avatar
    Science Advisor
    Homework Helper

    You can't tell how many places a number has once you convert it into floating point.
    The computer stores floating point as an approximation.

    To count the number of digits you would have to do it while it is still a string - so find the position of the '.' and the second ':' characters in the string and count the number of characters between them.
     
  12. Nov 1, 2008 #11
    thanks to mgb phys for all your help!
     
    Last edited: Nov 1, 2008
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?



Similar Discussions: C newbie on strings and arrays (Urgent, due monday)
  1. C - array (Replies: 2)

Loading...