Go: package main

import (
	"bufio"
	"os"
	"strings"
	"strconv"
	"fmt"
)

func check(x, y, x1, y1, x2, y2 float64) float64 {
	return (x2-x1)*y - (y2-y1)*x + x1*y2 - x2*y1
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	a := make([]float64, 8)
	for scanner.Scan() {
		info := strings.Split(scanner.Text(), ",")
		for j := 0; j < 8; j++ {
			a[j], _ = strconv.ParseFloat(info[j], 64)
		}
		if check(a[0], a[1], a[2],a[3], a[6], a[7])*check(a[4], a[5], a[2], a[3], a[6], a[7]) < 0 && check(a[6], a[7], a[0], a[1], a[4], a[5])*check(a[2],a[3], a[0], a[1], a[4], a[5]) < 0 {
			fmt.Println("YES")	
		} else {
			fmt.Println("NO")
		}
	}
}

C++: #include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#define EPS 1e-10
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define pb push_back
#define pop pop_back
using namespace std;
typedef pair<double,int> Pos;

struct Point{
  double x,y;
  Point(double x=0,double y=0):x(x),y(y){}
  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (Point p){return Point(x*p.x,y*p.y);}
  Point operator / (Point p){return Point(x/p.x,y/p.y);}
  double dot(Point p){
    return x*p.x+y*p.y;
  }
  double cross(Point p){
    return x*p.y-y*p.x;
  }
  double norm(){
    x*x+y*y;
  }
  double abs(){
    return sqrt(norm());
  }
  bool operator < (const Point &p) const{
    return x != p.x ? x<p.x:y<p.y;
  }
  bool operator == (const Point &p) const{
    return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
  }
};
int ccw(Point p1,Point p2,Point p3){
  Point a = p2-p1;
  Point b = p3-p1;
  if(a.cross(b) > EPS)return COUNTER_CLOCKWISE;
  if(a.cross(b) < -EPS)return CLOCKWISE;
  if(a.dot(b) < -EPS)return ONLINE_BACK;
  if(a.norm() < b.norm())return ONLINE_FRONT;
  return ON_SEGMENT;
}

bool cmp_x(const Point& p,const Point& q){
  if(p.x!=q.x)return p.x<q.x;
    return p.y<q.y;
}

vector<Point> convex_hull(Point* ps,int n){
  sort(ps,ps+n,cmp_x);
  int k=0;
  vector<Point> qs(n*2);
  for(int i=0;i<n;i++){
    while(k>1 && (qs[k-1]-qs[k-2]).cross(ps[i]-qs[k-1])<=0)k--;
    qs[k++] = ps[i];
  }
  for(int i=n-2,t=k;i>=0;i--){
    while(k>t && (qs[k-1]-qs[k-2]).cross(ps[i]-qs[k-1])<=0)k--;
    qs[k++] = ps[i];
  }  
  qs.resize(k-1);
  return qs;
}

bool isIntersect(Point p1,Point p2,Point p3,Point p4){
  return (ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0 && ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0);
}


int main(){
  Point p1,p2,p3,p4;
  Point poly[5];
  
  while(scanf("%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf",&p1.x,&p1.y,&p2.x,&p2.y,&p3.x,&p3.y,&p4.x,&p4.y) != EOF){
    double sum=0;    
    poly[0] = p1;poly[1] = p2;poly[2] = p3;poly[3]=p4;poly[4]=p1;
    if(isIntersect(p1,p4,p2,p3)){
      cout << "NO"<< endl;
      continue;
    } 

    vector<Point> pos = convex_hull(poly,4);

    if(pos.size() <= 3)cout << "NO" << endl;
    else cout << "YES" << endl;


  }
  return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;

typedef long long int ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pair<int, int> > vii;
#define rrep(i, m, n) for(int (i)=(m); (i)<(n);  (i)++)
#define erep(i, m, n) for(int (i)=(m); (i)<=(n); (i)++)
#define  rep(i, n)    for(int (i)=0; (i)<(n);  (i)++)
#define rrev(i, m, n) for(int (i)=(n)-1; (i)>=(m); (i)--)
#define erev(i, m, n) for(int (i)=(n); (i)>=(m); (i)--)
#define  rev(i, n)    for(int (i)=(n)-1; (i)>=0; (i)--)
#define vrep(i, c)    for(__typeof((c).begin())i=(c).begin(); i!=(c).end(); i++)
#define  ALL(v)       (v).begin(), (v).end()
#define mp            make_pair
#define pb            push_back
template<class T, class S> inline bool minup(T& m, S x){ return m>(T)x ? (m=(T)x, true) : false; }
template<class T, class S> inline bool maxup(T& m, S x){ return m<(T)x ? (m=(T)x, true) : false; }

const int    INF = 1000000000;
const ll     MOD = 1000000007LL;
const double EPS = 1E-12;

struct Point : public complex<double>
{
public:
  Point() { this->real(0);  this->imag(0); }
  Point(const double& x, const double& y) { this->real(x);  this->imag(y); }
  Point(const complex<double> w)  { this->real(w.real());  this->imag(w.imag()); }
  inline double dot(Point p){ return (conj(*this) * p).real(); }  // ??????
  inline double det(Point p){ return (conj(*this) * p).imag(); }  // ??????
};

namespace std
{
  bool operator < (const Point& a, const Point& b)
  {
    return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
  }
}

int ccw(Point a, Point b, Point c)
{
  b -= a;
  c -= a;
  if(b.det(c) > 0.0)    return  1;
  if(b.det(c) < 0.0)    return -1;
  if(b.dot(c) < 0.0)    return  2;
  if(norm(b) < norm(c)) return -2;
  return 0;
}

typedef vector<Point> Polygon;


#define curr(P, i) P[(i) % P.size()]
#define next(P, i) P[(i+1) % P.size()]
#define prev(P, i) P[(i+P.size()-1) % P.size()]
bool isConvex(const Polygon &P) {
  for (int i = 0; i < P.size(); ++i)
    if (ccw(prev(P, i), curr(P, i), next(P, i)) > 0) return false;
  return true;
}

// O(nlogn)
vector<Point> AndrewMonotoneChain(vector<Point> ps)
{
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  vector<Point> ch(2*n);
  for(int i=0; i<n; ch[k++]=ps[i++]) // lower-hull
    while(k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  for(int i=n-2, t=k+1; i>= 0; ch[k++]=ps[i--]) // upper-hull
    while(k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  ch.resize(k-1);
  return ch;
}


template<typename T> ostream& operator <<(ostream& r, const vector<T> t){vrep(v,t)r<<*v<<(v+1==t.end()?"":" ");return r;}
template<typename T> ostream& operator <<(ostream& r, const pair<vector<T>, int> p){int n=p.second;minup(n,p.first.size());rep(i,n-1)r<<p.first[i]<<' ';r<<p.first[n-1];return r;}
template<typename T> ostream& operator <<(ostream& r, const pair<T*, int> p){int n=p.second-1;rep(i,n)r<<p.first[i]<<' ';return r<<p.first[n];}
template<typename T, size_t S> ostream& operator <<(ostream& r, const T (&a)[S]){rep(i,S-1)r<<a[i]<<' ';return r<<a[S-1];}


double x, y;
bool ok = true;

int main()
{
  while(~scanf("%lf,%lf", &x, &y)){
    Polygon P;
    P.pb(Point(x, y));
    rep(i, 3){
      scanf(",%lf,%lf", &x, &y);
      P.pb(Point(x, y));
    }

    cerr << P << endl;
    //    puts(isConvex(P) ? "NO" : "YES");
    puts(AndrewMonotoneChain(P) == P ? "YES" : "NO");
  }

  return 0;
}

C++: #include <iostream>
#include <vector>
#include <complex>
//#include <fstream>	// require freopen

using namespace std;

typedef complex <double> P;

#define EPS (1e-10)
#define EQ(a,b) (abs((a)-(b)) < EPS)

// OÏ (cross product) : a~b = |a||b|sinÆ
double cross(P a, P b) {
  return (a.real() * b.imag() - a.imag() * b.real());
}

int main()
{
//	cut here before submit 
//	freopen("testcase.ic", "r", stdin);
	string str = "";

	while (getline (cin, str ) ){
		while (str.find(',') != string::npos ){
			str = str.replace(str.find(','), 1, " " );
		} // end while

		stringstream ss (str );
		vector <P> p(4);
		int i;

		for (i = 0; i < 4; ++i){
			ss >> p[i].real() >> p[i].imag();
		} // end for

		if ( (    cross (p[1] - p[0], p[2] - p[0] ) > 0.0 
			&& cross (p[2] - p[1], p[3] - p[1] ) > 0.0
			&& cross (p[3] - p[2], p[0] - p[2] ) > 0.0
			&& cross (p[0] - p[3], p[1] - p[3] ) > 0.0
		      )
		||    (
   			   cross (p[1] - p[0], p[2] - p[0] ) < 0.0 
			&& cross (p[2] - p[1], p[3] - p[1] ) < 0.0
			&& cross (p[3] - p[2], p[0] - p[2] ) < 0.0
			&& cross (p[0] - p[3], p[1] - p[3] ) < 0.0
		      )
		){
			cout << "YES" << endl;
		}else{
			cout << "NO" << endl;
		} // end if

	} // end while
		
	return 0;
}