Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> чтение из файла float значений 
:(
    Опции темы
r00t_aka_spin
Дата 29.9.2007, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 29.9.2007

Репутация: нет
Всего: нет



Есть текстовый файл содержащий числа с плавающей точкой

Код

-5.21025937050581E-0001  2.32213917188346E-0001
-2.99051026813686E+0000  5.73992113117129E+0000
 4.49050202965736E+0000  7.32700684573501E+0000
 9.27351134829223E+0000  1.82522133458406E+0000
-4.59152134135365E+0000 -8.66918832529336E+0000
-1.79429247044027E+0000 -1.68778934981674E+0000


Требуется считать эти числа во float переменные. 

P.S. Знаю что можно выдернуть всё регексами, но каждый раз это  делать надоедает. Не верю что нет встроеных распознавалок чисел на уровне считывания, как например в Delphi или в C++

PM MAIL   Вверх
marcusmae
Дата 30.9.2007, 00:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



Ты имеешь в виду типа
Код

fscanf(file, "%f %f", &num1, &num2);

?

Да, думаю, таких функций нет. Но и
Цитата(r00t_aka_spin @  29.9.2007,  23:47 Найти цитируемый пост)
выдернуть всё регексами

- явный перебор по сложности, ведь можно читать построчно, а для выделения значений пользоваться Split-ом, как показано, например, здесь.

Если совсем не годится использовать двоичные/типизированные файлы, то можно выкрутиться, используя Managed C++ (для них даже появились более надёжные версии с суффиксом _s - fscanf_s), написать обёртку и использовать в C#.


Это сообщение отредактировал(а) marcusmae - 30.9.2007, 00:21


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
r00t_aka_spin
Дата 30.9.2007, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 29.9.2007

Репутация: нет
Всего: нет



Код

fscanf(file, "%f %f", &num1, &num2);


да, именно это и имею в виду. 
Большое спасибо за Split, забыл про него. привык всё регексами делать.
PM MAIL   Вверх
marcusmae
Дата 30.9.2007, 01:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



Хм, да не за что  smile
Несмотря на то, что Вы уже вполне довольны, я таки осуществил свою угрозу по написанию обёртки :

Код

#pragma once

#include "stdio.h"

using namespace System;

namespace LegacyFileScanning {

    class NativeFile  {

    public :
        FILE* stream;

    public :
        int lastError;

        NativeFile(char* path) {
            this->lastError = 0;
            if ( fopen_s(&stream, path, "r") != 0 )
                lastError = -1;
        }

        ~NativeFile(void) { fclose(stream); }
    };

    public ref class File {

    private :
        NativeFile* nativeFile;

    public :
        void ScanF(String^ format, array<float>^ %args) {
            // Split format string into tokens by space.
            array<String^>^ tokens = format->Split(nullptr);

            for (int tokenIndex = 0; tokenIndex < tokens->Length; tokenIndex++)
            {
                // Promote token to char-string.
                char* chToken = new char[tokens[tokenIndex]->Length];
                for (int index = 0; index < tokens[tokenIndex]->Length; index++)
                    chToken[index] = (char)tokens[tokenIndex][index];
                chToken[tokens[tokenIndex]->Length] = '\0';

                float val;
                fscanf_s(this->nativeFile->stream, chToken, &val);
                args[tokenIndex] = val;
            }
        }

        File(String^ path) {
            // Convert path.
            char* chPath = new char[path->Length + 1];
            for (int index = 0; index < path->Length; index++)
                chPath[index] = (char)path[index];
            chPath[path->Length] = '\0';

            this->nativeFile = new NativeFile(chPath);
            if (this->nativeFile->lastError == -1)
                throw gcnew ArgumentException("Cannot open the specified file.");
        }

        ~File(void) { delete this->nativeFile; }
    };
}


Тут написан native класс NativeFile, в котором хранится дескриптор файла и его managed сателлит - класс File, в котором есть функция ScanF, которая делает частное применение fscanf для вещественных данных.

Далее, тестовая программка уже на диезе :

Код

using System;
using System.Collections.Generic;
using System.Text;
using LegacyFileScanning;

namespace TestApp
{
    class Program
    {
        static string path = "data.txt";

        static void Main(string[] args)
        {
            File file = new File(path);
            float[] values = new float[2];
            file.ScanF("%f %f", ref values);

            Console.WriteLine(values[0]);
            Console.WriteLine(values[1]);
            Console.ReadKey();
        }
    }
}


Output для ваших данных :
Код

-0.521026
0.2322139


Как и требовалось, считалась первая строчка файла  smile

Это решение, конечно, "не для прессы", между нами  smile  Однако, вполне рабочее. При большом желании, его можно значительно приблизить к настоящему fscanf, применив список аргументов переменной длины (params - в плюсах это будет три точки : ...) и по-аккуратнее конвертируя wide-строки в мультибайтовые.

Impossible is nothing!

В прикреплённом архиве - весь solution c двумя проектами. Тока скомпильте заново, а то пришлось подрезать бинарники из-за ограничения размера...

Это сообщение отредактировал(а) marcusmae - 30.9.2007, 01:28

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  ScanExample.rar 102,57 Kb


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
r00t_aka_spin
Дата 30.9.2007, 19:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 29.9.2007

Репутация: нет
Всего: нет



я в C++ не особо силён, но постараюсь разобраться в работе класса, добавлю так же возможность считывать int и другие численные типы. ещё раз большое спасибо.
PM MAIL   Вверх
okaton
Дата 1.10.2007, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 213
Регистрация: 24.11.2006

Репутация: нет
Всего: нет



r00t_aka_spin, не знаю актуально для вас это сейчас или нет

Код

float[] shorts;
            using (BinaryReader br = new BinaryReader(File.OpenRead("Single.Float")))
            {
                List<float> res = new List<float>();
                for (Int32 i = 0; br.BaseStream.Position < br.BaseStream.Length; i++)
                    res.Add(br.ReadSingle());
                shorts = res.ToArray();                
            }    

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0458 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.