crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Проблема с консольным приложением, Какой-то неуловимый глюк, всю голову уже сломал...
x-8973
  опции профиля:
сообщение 22.2.2013, 10:18
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 25
Регистрация: 22.2.2013
Пользователь №: 3720

Спасибо сказали: 0 раз(а)




Репутация:   0  


Всем бобра!
Второй день бьюсь с консольным приложением, пытаясь найти и искоренить странный глюк. Приложение должно запросить у пользователя два имени файлов, обработать первый из них и записать результаты во второй. Проблема состоит в том, что сразу после ввода первого имени файла программа вываливается в критическую ошибку "память не может быть written". Если закомментировать весь код, оставив только ввод имен файлов, то прорабатывают оба ввода и прога останавливается. Ничего понять не могу. Может, здесь кто поможет?
Код main.cpp:
Раскрывающийся текст
#include <QtCore/QCoreApplication>
#include "cut-off_proc.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    printf("Enter name of file 1: ");
    scanf("%s", ch1);
    fileName1 = QString::fromAscii(ch1);
    printf("Enter name of file 2: ");
    scanf("%s", ch2);
    fileName2 = QString::fromAscii(ch2);
    /*file1.setFileName(fileName1);
    if (file1.open(QIODevice::ReadOnly))
    {
        QTextStream t(&file1);
        while (!t.atEnd())
        {
            str = t.readLine();
            if ((str.section(" ", 0, 0).compare("#"))&&(!str.isEmpty()))
            {
                number = str.section(" ", 0, 0);
                strCount = str.section(" ", 1, 1).toInt(&ok);
                for (int i = 0; i < strCount; i++)
                {
                    str = t.readLine();
                    if (!str.compare("fail"))
                    {
                        list1.clear();
                        list2.append(number+" fail");
                        break;
                        //вернуться в начало цикла while
                    }
                    if (!str.compare("restart"))
                    {
                        list1.clear();
                        break;
                        //вернуться в начало цикла while
                    }
                    list1.append(str.section(" ", 1, 1).toInt(&ok));
                } //end of "for"
                if (list1.isEmpty())
                    continue;
                mainTimeMS = list1.at(list1.count()-1)-list1.at(0);
                //calculating of time mm:ss.ms
                int min=0, sec=0, msec=0;
                QString min_s, sec_s, msec_s;
                sec =  mainTimeMS / 1000;
                msec = mainTimeMS - sec * 1000;
                min = sec / 60;
                sec = sec - min * 60;
                if (min < 10)
                    min_s = "0";
                if (sec < 10)
                    sec_s = "0";
                if (msec < 10)
                    msec_s = "0";
                if (msec < 100)
                    msec_s.append("0");
                min_s.append(QString::number(min));
                sec_s.append(QString::number(sec));
                msec_s.append(QString::number(msec));
                mainTimeMSMS = min_s+":"+sec_s+"."+msec_s;
                //end of calculating
                list2.append(number+" "+mainTimeMSMS+" "+QString::number(mainTimeMS));
                list1.clear();
            } //end of "if"
        }
        file1.close();
    }
    else
        printf("CRITICAL ERROR: Couldn't open file %s", fileName1.toAscii().data());
    if (!list2.isEmpty())
    {
        file2.setFileName(fileName2);
        if (file2.open(QIODevice::Append))
        {
            QTextStream t2(&file2);
            for (int i = 0; i < list2.count(); i++)
            {
                printf("%s", list2.at(i).toAscii().data());
                t2<<list2.at(i)<<"\n";
            }
            file2.close();
        }
        else
            printf("CRITICAL ERROR: Couldn't open file %s", fileName2.toAscii().data());
    }*/
    return a.exec();
}

Код cut-off_proc.h:
Раскрывающийся текст
#ifndef CUTOFF_PROC_H
#define CUTOFF_PROC_H

#endif // CUTOFF_PROC_H
#include <QFile>
#include <QTextStream>
#include <QString>
#include <QList>
#include <iostream>

QString str;
QString number, mainTimeMSMS;
int strCount, mainTimeMS;
bool ok;
QFile file1, file2;
QList<int> list1;
QList<QString> list2;
QString fileName1, fileName2;
char *ch1, *ch2;

Вот скрин ошибки:

Эскизы прикрепленных изображений
Прикрепленное изображение
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.2.2013, 10:24
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1603
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


char *ch1, *ch2;

 scanf("%s", ch1);

куда ты пишешь? в пустой указатель? естественно, будет ошибка. память должна быть выделена, перед тем, как туда что-то писать.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
x-8973
  опции профиля:
сообщение 22.2.2013, 10:51
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 25
Регистрация: 22.2.2013
Пользователь №: 3720

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Iron Bug @ 22.2.2013, 12:24) *
char *ch1, *ch2;

 scanf("%s", ch1);

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


Вот этот код прекрасно работает:
Раскрывающийся текст
#include <QtCore/QCoreApplication>
#include <QFile>
#include <QString>
#include <iostream>
#include <stdio.h>
#include <QTextStream>
using namespace std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QString filename;
    char *aa;
    printf("Enter filename: ");
    scanf("%s", aa);
    filename = QString::fromAscii(aa);
    QFile file;
    file.setFileName(filename);
    if (file.open(QIODevice::ReadOnly))
    {
        QTextStream t(&file);
        while (!t.atEnd())
        {
            printf("%s\n", t.readLine(0).toAscii().data());
        }
    }
    printf("%s", filename.toAscii().data());
    return a.exec();
}


Ладно, согласен, тут косяк. Но я же не знаю, какой длины имя файла введет пользователь. Соответственно, я не знаю, сколько памяти выделять.

Да, проблема оказалась в этом... Огромная глупость с моей стороне, это ведь еще на первом курсе проходят...
Еще один глупый вопрос: а сколько же все-таки нужно выделять памяти под имя файла? В Дельфи есть константа MAX_LEN, если мне память не изменяет. Может, и в QT что-то похожее есть?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 22.2.2013, 11:20
Сообщение #4


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


printf ("Enter the length of file name:");

:lol:
А если серьезно то лучше использовать QTextStream:
QTextStream str (stdin);

fileName1 = str.readLine ();
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Wlad
  опции профиля:
сообщение 22.2.2013, 11:43
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 9.12.2008
Пользователь №: 450

Спасибо сказали: 0 раз(а)




Репутация:   1  


Цитата
В Дельфи есть константа MAX_LEN, если мне память не изменяет. Может, и в QT что-то похожее есть?

Qt здесь не причем. Есть виндовая переменная MAX_PATH (определена в файле windef.h) равная 260 символам. Это и есть максимальная длина файла с путем к нему. Виндовые функции, работающие с файлами проверяют имя файла на эту длину Это ограничение можно объехать, но это другой вопрос.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.2.2013, 12:32
Сообщение #6


Профессионал
*****

Группа: Модератор
Сообщений: 1603
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


если пользоваться стандартным вводом и только под вендой, то можно использовать scanf_s.
длина имени файла, вообще говоря, зависит даже не от оси, а от файловой системы. в принципе, можно просто взять какое-то заведомо большое число.
однако, как написал lanz, если уж ты собрался юзать Qt, то логично воспользоваться потоками, которые эта библиотека предоставляет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
x-8973
  опции профиля:
сообщение 22.2.2013, 13:00
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 25
Регистрация: 22.2.2013
Пользователь №: 3720

Спасибо сказали: 0 раз(а)




Репутация:   0  


lanz, благодарствую)
Еще вопрос. Подумал, что раз уж юзать потоки, то юзать их и на выводе данных. Написал
QTextStream qcout(stdout);
qcout << "Enter name of file 1: ";

При запуске ничего не вывелось.
В принципе, не критично, printf в этом плане отлично справляется) Просто интересно, можно ли поток и для вывода данных использовать)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 22.2.2013, 13:30
Сообщение #8


фрилансер
******

Группа: Участник
Сообщений: 2913
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(x-8973 @ 22.2.2013, 13:51) *
Вот этот код прекрасно работает:

повезло )))

Цитата(x-8973 @ 22.2.2013, 13:51) *
Но я же не знаю, какой длины имя файла введет пользователь. Соответственно, я не знаю, сколько памяти выделять.

это в общем случае вполне решабельно: считывать по 1 символу и накапливать в буфере

А инициализировать переменные всё равно нужно :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 25.2.2013, 9:21
Сообщение #9


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


QTextStream outstr (stdout);
outstr << "Hello";
outstr.flush ();

Буфер приходится чистить вручную.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 7.3.2021, 3:25