Especifícamente el error que te da, puede ser que sea porque usas "header" y para poder usar esta no debes tener codigo html encima de donde está esta función.
He hecho un código que funciona, pero primero te voy a decir el porqué tu forma no es eficiente:
Para empezar, dentro del while, estás todo el rato haciendo la función explode al principio. Esto no es necesario (ni siquiera es necesario usarla realmente) ya que si sabes que el usuario no corresponde con el usuario, para qué partirlo y gastar recursos?
Por otra parte, cuando uses "if"s de una línea, no pongas llaves para que se vea más limpio.
Por último y respecto al tema de seguridad, si haces lo de header:location, cualquiera que sepa la localización del que da como true, puede acceder (a no ser que lo securices). Yo recomendaria hacer includes.
Ahora, te paso el código que he hecho, el cual obviamente, es una prueba. Por cierto, para otra vez, pon el código entre los tags adecuados para que se vea mejor:
$user = "user4";
$pass = "pass4";
$f=fopen("text.txt","r");
//Pregunto si la linea empieza por el nombre de usuario dado, y si le sigue la barra vertical
//En caso de ser correcto, compruebo que empiece por el nombre de usuario, contenga la barra, y acabe en la contraseña.
if(preg_match("/(^".$user.")\|(".$pass."$)/",$linea)) echo "ENTRO";
else
echo "FALSO";
else
echo "FALSO";
}
Nota: las contraseñas están en el formato especificado, pero muy importante, para que funcione con lo que he puesto, el texto ha de estar en formato de Unix, sino no reconoce el símbolo $ (final de línea) de las expresiones regulares tal como deberia.
Un saludo!