Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Работа с txt файлом


Автор: gromo 6.8.2011, 10:34
есть текстовый файл с вот таким содержимым (вместо "..." некий текст):
Цитата

...
 РАСШИРЕННАЯ ПЕЧАТЬ. Относит. время (час) =     0.000000E+00
...
...
...
      PsiAvr  PsiMax      ShAvr   ShMax
16   0.477   0.611/  67  11.474  25.426/  15
15   0.784   1.007/  67  18.031  38.975/  62
14   0.945   1.206/  32  20.567  43.627/  15
13   1.030   1.332/  31  21.372  44.921/  15
12   1.083   1.404/  31  21.650  45.262/  15
11   1.117   1.445/  52  21.804  45.422/  82
10   1.140   1.470/  31  21.937  45.624/  82
 9   1.155   1.484/  31  22.071  45.841/  82
 8   1.162   1.489/  31  22.209  46.077/  82
 7   1.162   1.485/  31  22.353  46.328/  82
 6   1.154   1.472/  31  22.501  46.599/  82
 5   1.136   1.448/  31  22.642  46.880/  82
 4   1.103   1.413/  31  22.704  47.054/  82
 3   1.042   1.350/  31  22.364  46.508/  82
 2   0.912   1.196/  31  20.419  43.007/  62
 1   0.595   0.778/  31  13.591  29.414/  15
...
итак далее 

Мне нужно выбрать значение 0.000000E+00 после РАСШИРЕННАЯ ПЕЧАТЬ. Относит. время (час) =, а также все значения после      PsiAvr  PsiMax      ShAvr   ShMax.
Пытаюсь сделать вот так:
Код

void MFCDlg::OnGetdatafromtxt() 
{
    double array[255];
    char ch;
    CString g[233];
 FILE *pFile = fopen ("file.txt","r");
while(true)
{
    if((ch=fgetc(pFile)) != EOF){

        if(fscanf(pFile, "РАСШИРЕННАЯ ПЕЧАТЬ. Относит. время (час) =%s\n", g[0]) && fscanf(
pFile, "%s   %s   %s\/  %s  %s  %s\/  %s\n", g[1], g[2], g[3], g[4], g[5], g[6], g[7]))
                {
//далее работаем с массивом "g"
                }
    }
    else break;
}
fclose (pFile);
}

но не получается.
Помогите, пожалуйста, решить эту задачу

Автор: borisbn 6.8.2011, 15:18
Цитата(gromo @  6.8.2011,  10:34 Найти цитируемый пост)
но не получается.

ещё бы. fscanf при нахождении %s в форматной строке ждёт, что ему дадут указатель на char в качестве параметра, который нужно заполнять, а он получает... класс CString. Разницу чуешь ?
В общем см. в сторону регулярных выражений (хз. есть ли они в MFC, в boost - точно есть)

Добавлено через 11 минут и 28 секунд
Алгоритм должен быть примерно следующий (псевдокод)
Код

const int MAX_STR_LEN = 1024;
char str[ MAX_STR_LEN ];

FILE *pFile = fopen ( "file.txt", "rt" );
if ( pFile == 0 ) {
    return false;
}
while ( ! feof( pFile ) ) {
    if ( gets( str, MAX_STR_LEN, pFile ) != 0 ) {
        reg_ex reg_1 = ( "РАСШИРЕННАЯ ПЕЧАТЬ. Относит. время (час) = (.*)" );
        reg_ex reg_2 = ( "(\\d+)   (\\d+.\\d)   (\\d+.\\d)/  (\\d+)  (\\d+.\\d)  (\\d+.\\d)/  (\\d+)" );
        // если строка подходит под reg_1, то вытащить из него строку с 000E+00
        // иначе, если строка подходит под reg_2, то вытащить из него все числа и сделать с ними то, что нужно
    }
}
fclose( pFile );

Автор: gromo 6.8.2011, 23:45
borisbn, отличная идея, но раньше с регулярками в С не работал
если не трудно помоги, пожалуйста, написать код для моего варианта

Автор: feodorv 7.8.2011, 10:09
А зачем такие сложности с регулярными выражениями?
Почему нельзя заставить работать scanf? Что-то вроде:

Код

char buf[1024];
float t;
BOOL hasTime = FALSE;

...

while( fgets( buf, sizeof(buf), pFile) != NULL )
{
  int d1, d2, d3;
  float f1, f2, f3, f4;

  if( sscanf( buf, "РАСШИРЕННАЯ ПЕЧАТЬ. Относит. время (час) = %e", &t) != EOF ) hasTime = TRUE;

  if( hasTime )
    if( sscanf( buf, "%d   %f   %f/  %d  %f  %f/  %d\n", &d1, &f1, &f2, &d2, &f3, &f4, &d3) != EOF )
      addLine( d1, f1, f2, d2, f3, f4, d3);
    else
       printf( "Invalid line: %s", buf);
}

if( ferror(pFile) ) ...

...


Честно говоря, не люблю scanf'ы и обычно разбираю строку ручками.

PS Очень неприятная у Вас конструкция с if( scanf && scanf )

Автор: gromo 10.8.2011, 00:43
Пытаюсь реализовать вот так:
Код

char buf[1024];
FILE *pFile = fopen("file.txt","r");
float t;

int d2, d3, SloiNo;
float f1, f2, f3, f4;
if(pFile){
    while(true){
        if((ch = fgetc(pFile)) != EOF){                
            if( fscanf( pFile, "РАСШИРЕННАЯ ПЕЧАТЬ. Относит. время (час) = %e", &t) ) hasTime = TRUE;
                        if( hasTime )
                                if( fscanf( pFile, "%d   %f   %f/  %d  %f  %f/  %d\n", &d1, &f1, &f2, &d2, &f3, &f4, &d3) ){
//...
                                 }
                                else  printf( "Invalid line: %s", buf);
                }
        }
}

но ничего не получается. В чём проблема?

Автор: borisbn 10.8.2011, 08:13
gromo, 
1. Где выход из
Цитата(gromo @  10.8.2011,  00:43 Найти цитируемый пост)
 while(true){

?
2. 
Цитата(gromo @  10.8.2011,  00:43 Найти цитируемый пост)
if((ch = fgetc(pFile)) != EOF){     

зачем это ?
3. fscanf возвращает количество переменных, которое она заполнила, а не true/false. Т.е., если заполнена даже одна переменная (а не все), то твоя конструкция if ( fscanf(...) ) отработает... а не должна.
4. (и самое главное)
Цитата(gromo @  10.8.2011,  00:43 Найти цитируемый пост)
но ничего не получается

- не компилируется ?
- компилируется, запускается и вылетает ?
- запускается, не вылетает, но работает не так, как задумано ?

кста, если последний вариант, то для этого существует отладчик...

и ещё: тебе feodorv дал рабочий вариант, который нужно всего чуть-чуть допилить до твеоих нужд ( заменить ... на то, что там должно быть и реализовать ф-цию addLine ). Чего не юзаешь ?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)