Práce s texťákem v C++ do C# – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Práce s texťákem v C++ do C# – .NET – Fórum – Programujte.comPráce s texťákem v C++ do C# – .NET – Fórum – Programujte.com

 

ORION206
~ Anonymní uživatel
23 příspěvků
20. 2. 2018   #1
-
0
-

Ahoj,

PROSÍM o pomoc. Mám v C++ napsaný kod, díky kterému jsem schopen pracovat a eliminovat určitou část textáku a následně vypsat data do nového souboru. Jedná se o texťák se souřadnicemi a barevnou škálou: x, y, z, odrazivost, r, g, b.
Zápis v C++

#include "stdafx.h"
#include <iostream>     // std::cout
#include <fstream>      // std::ifstream
#include <string>
#include <sstream>
#include <time.h>
#include <ctime>

const int COLUMNS = 7;

struct radek
{
	float x;															//POZNAMKY:
	float y;																	//vytvorit funkci 
	float z;																	//vyhledat min, max z celeho Mracna souboru pro lepsi orientaci zadavani mezi - casova narocnost?????
	float odrazivost;															//zjistit kolik mista zabira radek - vytvorit deleni dle velikosti
	float r;																	//spravit datum time_t - VYVOLAT FUNKCI DATUM NA SPRÁVNÉM MÍSTĚ V KODU
	float g;
	float b;
};


using namespace std;

radek MakeRow(float pole[7])
{
	radek soucasnejRadek;
	soucasnejRadek.x = pole[0];
	soucasnejRadek.y = pole[1];
	soucasnejRadek.z = pole[2];
	soucasnejRadek.odrazivost = pole[3];
	soucasnejRadek.r = pole[4];
	soucasnejRadek.g = pole[5];
	soucasnejRadek.b = pole[6];

	return soucasnejRadek;
}
float main() 
{
	float mez_X[2];
	float mez_Y[2];
	float mez_Z[2];
	int pocetRadku;

		std::string filename; 
		std::string filenameOUT = "Vysledek_Cisla_Dle_Souradnic";

		std::ifstream ifs(filename.c_str(), std::ifstream::in);
		std::ofstream ofs(filenameOUT.c_str(), std::ofstream::out);
if (ifs.is_open() && ofs.is_open())
		{
			std::string line;
			while (std::getline(ifs, line))
			{
				std::istringstream ss(line);							
				radek soucasnejRadek;

				if (!(ss >> soucasnejRadek.x >> soucasnejRadek.y >> soucasnejRadek.z >> soucasnejRadek.odrazivost >> soucasnejRadek.r >> soucasnejRadek.g >> soucasnejRadek.b))
				{
					continue;
				}

				if (mez_X[0] <= soucasnejRadek.x && mez_X[1] >= soucasnejRadek.x)												
				{
					if (mez_Y[0] <= soucasnejRadek.y && mez_Y[1] >= soucasnejRadek.y)
					{
						if (mez_Z[0] <= soucasnejRadek.z && mez_Z[1] >= soucasnejRadek.z)
						{
							a++;
							pocetRadku = a;
							ofs << soucasnejRadek.x << " " << soucasnejRadek.y << " " << soucasnejRadek.z << " " << soucasnejRadek.odrazivost << " " << soucasnejRadek.r << " " << soucasnejRadek.g << " " << soucasnejRadek.b << '\n'; 
						}

					}

				}


			}
			ifs.close();
			ofs.close();
		}
		else
		{
			std::cout << "Error opening file";
		}

V podstatě jde o to, že mám vytvořenou strukturu s proměnýma a pak načítám jednotlivý řádek (může jich být v tom texťáku teřba i 40mil.) a dle podmínky vypisuju jednotlivé řádky do nového souboru. Tím prostě eliminuju to co nechci... Ale nejsem schopen tohle přepsat do C#. konkrétně nevím, jak vytvořit tu strukturu s polem (Radek (MakeRow(...)). A pak nevím jak na ten stringstream ss(line), kde přes operátor >> načítám data ze streamu a testuji stav streamu.

Neporadil by mi PROSÍM někdo, jak to přepsat do C#? Díky za každou radu.

Texťák vypadá asi tak

-2.527664 -6.172501 -1.749588 -1557 55 45 44
-18.999893 -22.491531 -0.102524 -1648 47 36 34
-24.240677 -24.054489 -0.108078 -1570 42 35 34
-24.530594 -25.052109 -1.108261 -1120 77 58 53
Nahlásit jako SPAM
IP: 91.139.6.–
KIIV
~ Moderátor
+43
God of flame
20. 2. 2018   #2
-
0
-

Misto makeRow je jednodussi mit proste konstruktor z pole hodnot.

Ten istringstream je tam pro zjednoduseni nacitani. Nacte se celej radek, tim se pak vytvori istringstream objekt a pak se pouzije pro ziskani pole hodnot. Zamer se na tu funkcionalitu, v C# se to bude pravdepodobne delat jinak.

Tady maji napriklad nasekani retezce intu: https://stackoverflow.com/a/2959196/5271927

Nahlásit jako SPAM
IP: 93.91.151.–
Program vždy dělá to co naprogramujete, ne to co chcete...
BDS+3
Věrný člen
20. 2. 2018   #3
-
0
-

#1 ORION206
to by celkem nebyl problém, ale hlavní chyba je v tom, že uvedený kód je špatně. (například vidím, že porovnáváš mez_X s něčím, přitom proměnné mez_X, mez_Y, mez_Z nemají přiřazenou hodnotu.) Takže by se to blbě přepisovalo.

Takže nejlépe bude když napíšeš co přesně má program dělat. Nebo to začni nějak montovat sám a pokud si nebudeš vědět rady s něčím konkrétním, tak se zeptáš.

ps, tady máš jednu z možností jak z pole udělat strukturu (pro začátečníka asi nejlépe pochopitelná)

    class Program
    {
        static void Main(string[] args)
        {
            float[] data_radku = new float[7]; //tady nějak data z řádku získáš (třeba tím splitem)
            Radek radek = new Radek(data_radku);
        }
    }

    struct Radek
    {
        public float x;
        public float y;
        public float z;
        public float odrazivost;
        public float r;
        public float g;
        public float b;

        public Radek(float[] data)
        {
            x = data[0];
            y = data[1];
            z = data[2];
            odrazivost = data[3];
            r = data[4];
            g = data[5];
            b = data[6];
        }
    };

Samozřejmě je nutné ošetřit chyby!

I když Nevím jestli je nutné tam vůbec tu strukturu dělat, s těmi daty by se mohlo pracovat rovnou v poli.

Nahlásit jako SPAM
IP: 185.69.69.–
W11 :)
BDS+3
Věrný člen
20. 2. 2018   #4
-
0
-

Tady je jednoduchá ukázka:

using System;
using System.Globalization;
using System.Threading;
using System.IO;

namespace ConsoleApp1
{
    class Program
    {
        const int X_VALUE = 0;
        const int Y_VALUE = 1;
        const int Z_VALUE = 2;
        const int REFLECT_VALUE = 3;
        const int R_VALUE = 4;
        const int G_VALUE = 5;
        const int B_VALUE = 6;

        static void Main(string[] args)
        {
            // aby to bralo tečku jako oddělovač
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

            try
            {
                using (StreamReader sr = new StreamReader("vstup.txt"))
                {
                    using (StreamWriter sw = new StreamWriter("vystup.txt", false))
                    {
                        ConvertFile(sr, sw);
                    }
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadKey();
            }
        }

        static void ConvertFile(StreamReader src, StreamWriter des)
        {
            src.BaseStream.Seek(0, SeekOrigin.Begin);
            while (true)
            {
                string line = src.ReadLine();
                if (line != null)
                {
                    try
                    {
                        float[] data = Array.ConvertAll(line.Split(' '), Single.Parse);
                        if (data.Length > 6)
                        {
                            if(data[X_VALUE] < -3.0f) //tady si udělěj porovnání jaké chceš
                            {
                                des.WriteLine( string.Format("{0} {1} {2} {3} {4} {5} {6}",
                                                              data[0], data[1], data[2], data[3], data[4], data[5], data[6]));
                                //nebo pokud tam nechceš nic měnit: des.WriteLine(line);
                            }
                        }
                    }
                    catch (Exception) { }
                }
                else break;
            }
        }
    }
}
Nahlásit jako SPAM
IP: 185.69.69.–
W11 :)
ORION206
~ Anonymní uživatel
23 příspěvků
21. 2. 2018   #5
-
0
-

#4 BDS
Ahoj,

díky moc! Ano to co jsem postoval jako první, tak jsem to vykopíroval z většího souboru, protože jsem to psal vše do jednoho, takže to nebude funkční. Spíše mi šlo o to, aby bylo zřejmé co to má dělat (to se snad povedlo. :-) ). To co jsi napsal ty je super a funguje, zkusím tam narvat více podmínek, akorát mě mrzí, že jsem to nedal sám. :-)

Akorát pokud se mohu zeptat, k čemu je přesně

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

tečka jako oddělovač, tím myslíš desetinou tečku/čárku?

Já se to ještě včera pokusil napsat nějak takhle

public struct Radek
{
    public float x;
    public float y;
    public float z;
    public float r;
    public float g;
    public float b;
}

namespace Pruhyb_VypisKonzole
{
    class Program
    {
        
        float[] pole = new float[6];

        Radek MakeRow(float[] pole)
        {
            Radek soucasnyRadek;
            soucasnyRadek.x = pole[0];
            soucasnyRadek.y = pole[1];
            soucasnyRadek.z = pole[2];
            soucasnyRadek.r = pole[3];
            soucasnyRadek.g = pole[4];
            soucasnyRadek.b = pole[5];

            return soucasnyRadek;
        }

        public static Stream ToStream(string s)
        {
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            writer.Write(s);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }

        static void Main(string[] args)
        {


            int pocetRadku;
            int a=0;
            float[] mez_X = new float[2];

            using (StreamReader sr = new StreamReader(@"soubor.txt"))
            {
                string line;
                while ((line=sr.ReadLine()) != null)
                {
                    string[] ss = line.Split(' ');
                    Radek soucasnyRadek;
                    soucasnyRadek.x = float.Parse(ss[0]);
                    soucasnyRadek.y = float.Parse(ss[2]);
                    soucasnyRadek.z = float.Parse(ss[4]);
                    soucasnyRadek.r = float.Parse(ss[6]);
                    soucasnyRadek.g = float.Parse(ss[9]);
                    soucasnyRadek.b = float.Parse(ss[11]);

                    using (StreamWriter sw = new StreamWriter(@"soubor1.txt", true))
                    {
                        if (mez_X[0] <= soucasnyRadek.x && mez_X[1] >= soucasnyRadek.x)
                        {
                            a++;
                            pocetRadku = a;
                            sw.WriteLine("{0}", "{1}", "{2}", "{3}", "{4}", "{5}", "{6}", "{7}", "{8}", "{9}", "{10}", "{11}\n", soucasnyRadek.x, ' ', soucasnyRadek.y, ' ', soucasnyRadek.z, ' ', soucasnyRadek.r, ' ', soucasnyRadek.g, ' ', soucasnyRadek.b);
                            //sw.WriteLine("{0}", "{1}", "{2}", "{3}", "{4}", "{5}", "{6}", "{7}\n", soucasnyRadek.x, ' ', soucasnyRadek.y, ' ', soucasnyRadek.z, ' ', soucasnyRadek.rgb);
                            sw.Flush();
                        }
                    }
                            //Console.WriteLine(stream);
                }

            }
            Console.ReadKey();
        }
    }
}

Ale to mi nefunguje, píše, že že vstupní řetězec nemá správný formát (řádek soucasnyRadek.x = float.Parse(ss[0]);)

Nahlásit jako SPAM
IP: 91.139.6.–
BDS+3
Věrný člen
21. 2. 2018   #6
-
0
-

#5 ORION206

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

je tam proto, že pokud používáš např. české windows tak by ti nefungovalo parsování čísla s desetinnou tečkou..

takže pokud tam máš tečku, jedeš např. na českých windows a nedáš tam "en-US", tak ti to nebude fungovat.

možná se ti může hodit i toto: 

                char[] del = new char[] { ' ' }; //možná tam můžeš mít i '\t'
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    string[] ss = line.Split(del, StringSplitOptions.RemoveEmptyEntries); //vynechá prázdné řetězce (např. 2 mezery za sebou)

mimochodem, proč tam máš to pole mez_X, když k němu nepřiřazuješ žádnou hodnotu?(u C# je tam 0, ale u C++ byla hodnota v závislosti na tom co bylo na dané pozici v paměti - v podstatě náhodné číslo)

proč do souboru zapisuješ 12 argumentů, když jich tam máš pouze 6?

Nahlásit jako SPAM
IP: 94.113.253.–
W11 :)
BDS+3
Věrný člen
21. 2. 2018   #7
-
0
-

až teď jsem si všiml, jak máš řešeno WriteLine..

vkládat tam mezery zvlášť je zbytečné, stačí to udělat takto: 

WriteLine("{0} {1} {2} {3} {4} {5}", soucasnyRadek.x, soucasnyRadek.y, soucasnyRadek.z, 
 soucasnyRadek.r, soucasnyRadek.g, soucasnyRadek.b);

pokud tam nechceš vkládat jeden prázdný řádek, můžeš "\n" vynechat

Nahlásit jako SPAM
IP: 185.69.69.–
W11 :)
BDS+3
Věrný člen
21. 2. 2018   #8
-
0
-

#5 ORION206
Tady jsem ti z nudy udělal ještě jednu ukázku:  

using System;
using System.Globalization;
using System.IO;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ConvertFile("vstup.txt", "vystup.txt", -220.0f, 16.0f);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadKey();
            }
        }
        /// <summary>
        /// konverze souboru
        /// </summary>
        /// <param name="src">vstupní textový soubor</param>
        /// <param name="des">výstupní textový soubor</param>
        /// <param name="min_X">minimální povolená hodnota X</param>
        /// <param name="max_X">maximální povolená hodnota X</param>
        static void ConvertFile(string src, string des, float min_X, float max_X)
        {
            NumberFormatInfo nfi = new NumberFormatInfo()//nahrazuje změnu CurrentCulture
            {
                NumberDecimalSeparator = "."
            };

            using (StreamReader sr = new StreamReader(src))
            {
                using (StreamWriter sw = new StreamWriter(des, false))
                {
                    char[] del = new char[] { ' ' };
                    int row_number = 1; // 0
                    Radek soucasnyRadek;
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        try
                        {
                            string[] ss = line.Split(del, StringSplitOptions.RemoveEmptyEntries);
                            soucasnyRadek.x = float.Parse(ss[0], nfi);
                            soucasnyRadek.y = float.Parse(ss[2], nfi);
                            soucasnyRadek.z = float.Parse(ss[4], nfi);
                            soucasnyRadek.r = float.Parse(ss[6], nfi);
                            soucasnyRadek.g = float.Parse(ss[9], nfi);
                            soucasnyRadek.b = float.Parse(ss[11], nfi);

                            if (soucasnyRadek.x >= min_X && soucasnyRadek.x <= max_X) //tady si udělěj porovnání jaké chceš
                            {
                                sw.WriteLine(soucasnyRadek.ToString(nfi));
                            }
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("Chybný řádek: {0}", row_number);
                            throw; //pokud chceš konverzi při chybě ukončit
                        }
                        row_number++;
                    }
                }
            }
        }
    }

    public struct Radek
    {
        public float x;
        public float y;
        public float z;
        public float r;
        public float g;
        public float b;

        public string ToString(NumberFormatInfo nfi)
        {
            return string.Format(nfi, "{0} {1} {2} {3} {4} {5}", x, y, z, r, g, b);
        }
        //public override string ToString()//výchozí formát
        //{
        //    return string.Format("{0} {1} {2} {3} {4} {5}", x, y, z, r, g, b);
        //}
    }
}
Nahlásit jako SPAM
IP: 185.69.69.–
W11 :)
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 77 hostů

Podobná vlákna

Prace — založil Anonymní uživatel

Práce ve VB — založil Ata2

Práce v IT — založil Michal

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý