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 <stack>
#include <queue>
#include <map>
#include <bitset>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>

#define X first
#define Y second
#define dis(a, b) (b.X - a) * (b.X - a) + (b.Y - a) * (b.Y - a)

using namespace std;

double cross(pair<double, double> lineA, pair<double, double> lineB){
	return (lineA.X * lineB.Y - lineB.X * lineA.Y) / sqrt(dis(0, lineB));
}

int main(){
	pair<double, double> pointA, pointB, pointC, pointD;
	while(scanf("%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf", &pointA.X, &pointA.Y, &pointB.X, &pointB.Y, &pointC.X, &pointC.Y, &pointD.X, &pointD.Y) != EOF){
		vector<pair<double, double> > point;
		point.push_back(pointA);
		point.push_back(pointB);
		point.push_back(pointC);
		point.push_back(pointD);
		bool hekomi = false;
		for(int i = 0; i < point.size(); i++){
			pair<double, double> lineA(point[(i + 1) % 4].X - point[i].X, point[(i + 1) % 4].Y - point[i].Y); 
			pair<double, double> lineB(point[(i + 2) % 4].X - point[i].X, point[(i + 2) % 4].Y - point[i].Y);
			if(cross(lineA, lineB) < 0){
				//cout << "\\\\\\\\\\\\\\\\\\" << endl;
				//cout << cross(lineA, lineB) << endl;
				//cout << "\\\\\\\\\\\\\\\\\\" << endl;
				hekomi = true;
				break;
			}
		}

		cout << (hekomi ? "NO" : "YES") << endl;
	}
	return 0;
}

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

typedef long double ld;

const ld EPS = 1e-9;
const ld INF = 1e10;
const ld PI = M_PI;

struct Point{
  ld x, y;
  Point(ld x, ld y):x(x), y(y){}
  Point(){}
};

Point operator+(const Point &a, const Point &b){
  return Point(a.x + b.x, a.y + b.y);
}
Point operator-(const Point &a, const Point &b){
  return Point(a.x - b.x, a.y - b.y);
}
Point operator*(const Point &a, const ld b){
  return Point(a.x * b, a.y * b);
}
Point operator*(const Point &a, const Point &b){
  return Point(a.x*b.x-a.y*b.y, a.x*b.y+a.y*b.x);
}
Point operator/(const Point &a, const ld b){
  return Point(a.x / b, a.y / b);
}

typedef vector<Point> Polygon;

Point next(const Polygon &a, int x){
  return a[(x+1)%a.size()];
}
Point prev(const Polygon &a, int x){
  return a[(x-1+a.size()) % a.size()];
}

ld cross(const Point &a, const Point &b){
  return a.x*b.y - a.y*b.x;
}

ld dot(const Point &a, const Point &b){
  return a.x*b.x + a.y*b.y;
}
ld norm(const Point &a){
  return dot(a, a);
}

int ccw(Point a, Point b, Point c){
  b = b - a;
  c = c - a;
  if(cross(b, c) > EPS) return +1; // 反時計周り
  if(cross(b, c) < -EPS) return -1; // 時計周り
  if(dot(b, c) < 0) return +2; // c -- a -- b がこの順番に一直線上
  if(norm(b) < norm(c)) return -2; // a -- b -- c がこの順番に一直線上
  return 0; // a -- c -- b が一直線上
}

bool is_convex(const Polygon &poly){
  for(int i = 0 ; i < (int)poly.size() ; i++){
    if(ccw(prev(poly, i), poly[i], next(poly, i)) == -1) return false;
  }
  return true;
}

int main(){
  ld x, y;
  char c;
  while(cin >> x >> c >> y >> c){
    Polygon poly;
    poly.push_back(Point(x, y));
    for(int i = 0 ; i < 2 ; i++){
      cin >> x >> c >> y >> c;
      poly.push_back(Point(x, y));
    }
    cin >> x >> c >> y;
    poly.push_back(Point(x, y));
    
    cout << (is_convex(poly) ? "YES" : "NO") << endl;
  }
  
  return 0;
}