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 <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <string>
#include <cmath>
#include <cstdio>
using namespace std;

#define PI 4*atan(1);

#define AB2 ((x[1] - x[0])*(x[1] - x[0]) + (y[1] - y[0])*(y[1] - y[0]))
#define BC2 (x[2] - x[1])*(x[2] - x[1]) + (y[2] - y[1])*(y[2] - y[1])
#define CD2 (x[3] - x[2])*(x[3] - x[2]) + (y[3] - y[2])*(y[3] - y[2])
#define DA2 (x[0] - x[3])*(x[0] - x[3]) + (y[0] - y[3])*(y[0] - y[3])
#define CA2 (x[0] - x[2])*(x[0] - x[2]) + (y[0] - y[2])*(y[0] - y[2])
#define BD2 (x[3] - x[1])*(x[3] - x[1]) + (y[3] - y[1])*(y[3] - y[1])

int main(){
  double x[4], y[4];
  while(scanf("%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf", &x[0],&y[0],&x[1],&y[1],&x[2],&y[2],&x[3],&y[3]) != EOF){
    bool rad = true;
    if((x[1] - x[0]) * (x[3] - x[0]) + (y[1] - y[0]) * (y[3] - y[0]) < 0){
      rad = false;
    }
    if((x[0] - x[3]) * (x[2] - x[3]) + (y[0] - y[3]) * (y[2] - y[3]) < 0){

      rad = false;
    }
    if((x[3] - x[2]) * (x[1] - x[2]) + (y[3] - y[2]) * (y[1] - y[2]) < 0){

      rad = false;
    }
    if((x[0] - x[1]) * (x[2] - x[1]) + (y[0] - y[1]) * (y[2] - y[1]) < 0){

      rad = false;
    }
    if(rad == true){
      cout << "YES" << endl;
    }else{
      cout << "NO" << endl;
    }
  }
}

C++: #include <stdio.h>
#include <iostream>
#include <vector>
#include <list>
#include <cmath>
#include <fstream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <iterator>
#include <cstdlib>
#include <sstream>

using namespace std;

#define EPS (1e-10)
#define EQ(a,b) (abs((a) - (b)) < EPS)
#define EQV(a,b) (EQ((a).real(),(b).real()) && EQ((a).imag(),(b).imag()))

typedef complex<double> P;
typedef long long ll;

const int MAX_SIZE = 10000;

double dot(P a, P b) {
  return (a.real() * b.real() + a.imag() * b.imag());
}
double cross(P a, P b) {
  return (a.real() * b.imag() - a.imag() * b.real());
}
using namespace std;

int main(){

	double x[4];
	double y[4];
	char cm;
	while(cin>>x[0]){
		cin>>cm;
		cin>>y[0];
		for(int i = 1; i < 4; i++){
			cin>>cm>>x[i]>>cm>>y[i];
		}
		// ツつサツづェツつシツづェツづ個角ツづ個角ツ度ツづーツ計ツ算ツつオツ、180ツ度ツづーツ越ツつヲツづゥツ角ツ度ツつェツ堕カツ催敖つキツづェツづ篠、ツつュツづ堋づアツづつ「ツづゥ
		complex<double> A1(x[1]-x[0],y[1]-y[0]);
		complex<double> A2(x[3]-x[0],y[3]-y[0]);
		complex<double> B1(x[2]-x[1],y[2]-y[1]);
		complex<double> B2(x[0]-x[1],y[0]-y[1]);
		complex<double> C1(x[3]-x[2],y[3]-y[2]);
		complex<double> C2(x[1]-x[2],y[1]-y[2]);
		complex<double> D1(x[0]-x[3],y[0]-y[3]);
		complex<double> D2(x[2]-x[3],y[2]-y[3]);
		if(cross(A1,A2)<0||cross(B1,B2)<0||cross(C1,C2)<0||cross(D1,D2)<0){
			cout<<"NO"<<endl;
		}
		else
			cout<<"YES"<<endl;
	}

	return 0;
}

C++: #include<iostream>
using namespace std;

#define turn(x1,y1,x2,y2,x3,y3) x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2)
int hantei(int ax,int ay,int bx,int by,int cx,int cy,int dx,int dy);
int main()
{
	int i;
	double xy[8];
	int ans;
	char a;
	
	for(;cin >> xy[0];)
	{
		for(i=1;i<8;i++)
			cin  >> a >> xy[i];
		
		ans=1;
		
		if(hantei(xy[0],xy[1],xy[2],xy[3],xy[4],xy[5],xy[6],xy[7])==0)
			ans=0;
		
		if(hantei(xy[2],xy[3],xy[4],xy[5],xy[6],xy[7],xy[0],xy[1])==0)
			ans=0;
		
		if(hantei(xy[4],xy[5],xy[6],xy[7],xy[0],xy[1],xy[2],xy[3])==0)
			ans=0;
		
		if(hantei(xy[6],xy[7],xy[0],xy[1],xy[2],xy[3],xy[4],xy[5])==0)
			ans=0;
		
		
		if(ans==1)
			printf("YES\n");
		else
			printf("NO\n");
	}
}

int hantei(int ax,int ay,int bx,int by,int cx,int cy,int dx,int dy)
{
	if((
		turn(ax,ay,bx,by,cx,cy)>0 &&
		turn(dx,dy,ax,ay,bx,by)>0 &&
		turn(dx,dy,bx,by,cx,cy)>0 &&
		turn(dx,dy,cx,cy,ax,ay)>0)
		||(
		turn(ax,ay,bx,by,cx,cy)<0 &&
		turn(dx,dy,ax,ay,bx,by)<0 &&
		turn(dx,dy,bx,by,cx,cy)<0 &&
		turn(dx,dy,cx,cy,ax,ay)<0)
	)
		return 0;
	else
		return 1;
}

C++: #include <iostream>
#include <cmath>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;

const double EPS = 1e-6;

double add(double a, double b) {
	if (abs(a + b) < EPS * (abs(a) + abs(b)))
		return 0;
	return a + b;
}

struct P {
	double x, y;
	P() {};
	P(double x, double y) : x(x), y(y) {
	}

	P operator + (P p) {
		return P(add(x, p.x), add(y, p.y));
	}

	P operator - (P p) {
		return P(add(x, -p.x), add(y, -p.y));
	}

	P operator * (double d) {
		return P(x * d, y * d);
	}

	P operator / (double d) {
		return P(x / d, y / d);
	}

	// 内積
	double dot(P p) {
		return add(x * p.x, y * p.y);
	}

	// 外積
	double det(P p) {
		return add(x * p.y, -y * p.x);
	}
};

// 線分上に点があるか
bool on_seg(P p1, P p2, P q) {
	return (p1 - q).det(p2 - q) == 0 && (p1 - q).dot(p2 - q) <= 0;
}

// 直線と直線の交点
P intersection(P p1, P p2, P q1, P q2) {
	return p1 + (p2 - p1) * ((q2 - q1).det(q1 - p1) / (q2 - q1).det(p2 - p1));
}

// 2直線の直行判定
bool line_orth(P a1, P a2, P b1, P b2) {
	return fabs((a1 - a2).dot(b1 - b2)) < EPS;
}

// 2直線の平行判定
bool line_paral(P a1, P a2, P b1, P b2) {
	return fabs((a1 - a2).det(b1 - b2)) < EPS;
}

// 進行方向
int ccw(P a, P b, P c) {
	b = b - a; c = b - c;
	if (b.det(c) > 0)
		return +1;
	else if (b.det(c) < 0)
		return -1;
	return 0;
}

int main(void) {
	string str;
	P p[4];
	while (getline(cin, str)) {
		replace(str.begin(), str.end(), ',', ' ');
		stringstream buf(str);
		for (int i = 0; i < 4; i++) {
			buf >> p[i].x >> p[i].y;
		}

		int a = 0, b = 0;
		for (int i = 0; i < 4; i++) {
			a += ccw(p[i], p[(i+1)%4], p[(i+2)%4]);
			b += abs(ccw(p[i], p[(i+1)%4], p[(i+2)%4]));
		}

		cout << (abs(a) == b ? "YES" : "NO") << endl;
	}
}