2012-06-29 9 views
6

En idioma alemán, los separadores decimales son, y los separadores de valores son ";" . En inglés/otros idiomas, los separadores decimales son. y los valores de separadores son ",".escribiendo un archivo .csv - independiente de la cultura

Quiero crear un archivo .csv independiente de la cultura actual. Quiero decir que siempre el archivo .csv debería tener "." tiene separadores decimales y "," tiene separadores de valores.

El código para esto se proporciona a continuación.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Globalization; 

namespace CSV_FILE_FORMAT 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string aFileName = "result.csv"; 
      FileStream aFileStream = new FileStream(aFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); 
      StreamWriter m_StreamWriter = new StreamWriter(aFileStream); 
      double[] values = new double[] { 10.5, 20.3, 30.2 }; 
      for(int i = 0; i < values.Length;i++) 
      { 
       m_StreamWriter.Write(values[i].ToString(CultureInfo.InvariantCulture)); 
       m_StreamWriter.Write(","); 
      } 
     } 
    } 
} 

El problema con este código es si el sistema operativo está en alemán. Los separadores decimales se muestran "," en lugar de ".".

Háganme saber que el código falta algo.

+2

_ "El problema con este código es si el sistema operativo está en alemán. Los separadores decimales se muestran", "en lugar de". "." _ Eso debería evitarse mediante el uso de 'CultureInfo.InvariantCulture'. Así que debe haber algo más que aún me pase por alto. –

+0

m_StreamWriter.Write (values ​​[i] .ToString (CultureInfo.InvariantCulture)); Estoy usando culture.invariantculture. pero aun así no puedo obtener el valor adecuado. – Raghav55

+1

El código proporcionado funciona bien (excepto para cerrar los recursos ;-)) en un sistema operativo alemán (Windows 7) y los dobles están formateados con un punto "." como se esperaba por los comentarios. Incluso si las configuraciones de cultivo están configuradas en ",". –

Respuesta

2

Una solución rápida para resolver el problema de la cultura alemana es incorporar esos valores dobles con comillas. Resultados:

English: "10.5","20.3","30.2" 
German: "10,5","20,3","30,2" 

http://en.wikipedia.org/wiki/Comma-separated_values

+0

En mi humilde opinión, esta sería una solución mejor, coherente con los analizadores de CSV – Indy9000

+2

Una versión de Excel en alemán espera que ';' se utilice como delimitador, sin embargo. – Joey

+0

Depende mucho de la parte del lector: alemán o Invariant. –

1

No hay una solución fácil a este problema: CSV es no una definición de formato de archivo (a pesar de RFC 4180).

Excel, por ejemplo, lee y guarda csv utilizando el separador de lista localizado y los formatos de datos localizados establecidos por el usuario. De esta forma, "Coma" en CSV no significa una coma, sino el separador de lista genérico (para muchos países de la UE este es el punto y coma, como dijo Tim Schmelter).

Si los valores están entre comillas, en general se tratan como cadenas. Excel intenta analizar elementos citados de una fila CSV de todos modos, por lo que puede parecer que funciona en casos muy especiales. El problema es que tanto el escritor como el lector de un archivo CSV deberían usar la misma cultura, de lo contrario surgirán problemas con casi todo lo que no es una cadena (los números son uno, la fecha/hora es otra fuente de problemas).

Uso una solución derivada empíricamente para las fechas, que consiste en el formato de cadena yyyy/MM/dd HH:mm:ss. Observé que permite el intercambio de fechas de trabajo entre Excel y mis programas, indistintamente en inglés o italiano.

Todavía no he encontrado una solución universal para números decimales. Sospecho que la notación científica puede hacer, pero no he tenido tiempo de probar.

6

Probablemente pueda obtener un separador decimal y un separador de lista del cultivo actual.

CultureInfo culture = new CultureInfo(currentCultureName); 
string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator; 
string listSeparator = culture.TextInfo.ListSeparator; 

Y, si el valor que se está escribiendo contiene alguno de los separadores, encierre el valor entre comillas dobles.

string val = values[i].ToString(CultureInfo.InvariantCulture); 
if(val.Contains(decimalSeparator) || val.Contains(listSeparator)) 
{ 
    val = string.Format("\"{0}\"", val); 
} 
m_StreamWriter.Write(val); 
m_StreamWriter.Write(listSeparator); 

nombre de la cultura actual puede ser algo como esto: "en-US" para los Estados Unidos de América.

Espero que esto ayude!