Good day!

I knew this is easy to all of you guys. But I need the most precise way to parse this string "45:50" and store the result in two dimensional array with int as datatype. The delimeter is ":".

Thank you!

Recommended Answers

All 13 Replies

Take a look at strtol for signed long integers or strtoul for unsigned long integers. In particular, look at the example from the first link; it could easily be made into a loop that can handle your problem.

Look at each character and convert to decimal. Easy peasy. strtoul() will take time and testing to understand, you can convert this by hand in 10 minutes.

@OP:

How about using sscanf()?

you can trying something like

sscanf(buffer, "%d:%d", &a, &b); // where buffer is your string

So, you can check the return value of sscanf(). If it returns 2, then it means your string had the necessary pattern. So, you can directly parse and read pattern into your variables.

PS: In fact you can actually match quite complex expressions using sscanf() to parse strings.

Member Avatar for iamthwee

Or you could use sstream... Again it all depends on your preference.

C++ is a multi-paradigmed language after all, if you choose to use c style solutions you can.

Jusy a try but Im having a closed loop. If I enter "45:50", it displays 45 only continously. My code so far:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
char input[5];
char * output; 

cout<<"Enter a string: ";
cin.getline(input,5);

  output=strtok(input,":");
  while(output != NULL)
   {
     cout<<output<<endl;
   }

  fflush(stdin);
  cin.get();
  return 0;
}

strtok() is funky in that it works using an internal state through multiple calls. To get the next token you need to call strtok() again with a null first argument (so that it knows to use the previously passed string):

output=strtok(input,":");
while(output != NULL)
{
    cout<<output<<endl;
    output=strtok(NULL,":");
}

Oh, and your input string and getline() call need to account for that pesky little '\0' at the end. Otherwise your last token ("CD") will be trimmed by a character because it's still stuck in the input stream.

Thank you deceptikon!
Ive modify the code. But when I enter "45:45" I get 45,4. The last character is missing. And also, fflush(stdin); cin.get() is not working.

  #include<iostream>
    #include<cstdio>
    using namespace std;
    int main()
    {
    char input[5];
    char * output;
    cout<<"Enter a string: ";
    cin.getline(input,5,'\0');
    output=strtok(input,":");
    while(output != NULL)
    {
    cout<<output<<endl;
    output=strtok(NULL,":");
    }
    fflush(stdin); //this does not work why?
    cin.get(); //this does not work why?
    return 0;
    }

fflush(stdin); //this does not work why?

It's not designed to work. See this.

cin.get(); //this does not work why?

That's because of cin.getline(input,5,'\0');. You left stuff in the input buffer. Just use cin.getline(input);

But when I enter "45:45" I get 45,4. The last character is missing.

char input[5]; isn't large enough. When you read a length of 5, you get 4 characters and the terminating '\0'. Define it as input[10] to be sure. On the other hand, why not just use a C++ string?

Also, your formatting needs work. See this, too.

But when I enter "45:45" I get 45,4. The last character is missing.

Read all of my reply next time, I predicted this problem and explained and how to fix it. Bump up the size of your array by 1, and account for that new size in your call to getline(). Adding '\0' as the third argument to getline() is silly and pointless because you'll never recieve that character value in any reasonable situation. It also does nothing to deal with the actual problem which is insufficient storage in the string to hold all of the input.

And also, fflush(stdin); cin.get() is not working.

fflush(stdin) isn't guaranteed to work. fflush() is only defined for output streams. But that's not the problem, the problem stems from the fact that you're trying to overfill your input string. getline() is smart enough to recognize that this is bad and puts cin into an error state, which you can see by adding one line before fflush():

cout << boolalpha << cin.fail() << '\n';
fflush(stdin);
cin.get();

You'll notice that it prints "true" because cin is in a failure state. Any requests for input either through fflush() (probably, I'm making an assumption about how your compiler's standard library works) and certainly get() will do nothing. The effect is like get() is implemented as so:

int istream::get()
{
    if (!good())
        return;

    // Do actual work...
}

If you fix the underlying failure, you'll fix the get() too. And if you fix the underlying failure properly by making sure the input string can hold any reasonably large line, you don't even need to worry about flushing the input stream:

#include <iostream>

using namespace std;

int main()
{
    char line[1024]; // Abritrary "big" size

    cout << "Enter a string: ";

    if (cin.getline(line, sizeof line)) {
        char *token = strtok(line, ":");

        while (token) {
            cout << token << '\n';
            token = strtok(0, ":");
        }
    }

    cout << "Press Enter to continue . . ." << flush;

    // No flush necessary because the stream was kept pristine
    cin.get();
}

Thank you WaltP, deceptikon!

Ive added the two dimensional array.

#include <iostream>
using namespace std;
int main()
{
    char line[1024]; // Abritrary "big" size
    int i, Num1Num2[1][1]={0};
    cout << "Enter a string: ";
    if (cin.getline(line, sizeof line)) 
    {
       char *token = strtok(line, ":");
       i=0;
           while (token) 
                 {
                  Num1Num2[i][i]=atoi(token);
                  cout << Num1Num2[i][i] << '\n';
                  token = strtok(0, ":");
                  i++;
                  }
    }
    //cout << "Press Enter to continue . . ." << flush;
    // No flush necessary because the stream was kept pristine
    cin.get();
}

And deceptikon, WaltP, that is well explained code. thank you!

int Num1Num2[1][1]={0};

What the heck is this? You set up a 2-dimensional single integer. Why? It's completely worthless.

Thank you WaltP!

Well, that two dimensional array is a preparation. Just because I want to extend the program to hold an output of 2 array in size with 5 elements. I would extend something like Num1Num2[2][5] later..

OK. That makes more sense. I thought you were having an aneurysm ;o)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.