1 Востаннє редагувалося yarko (06.02.2015 11:44:19)

Тема: Частина даних пропадає при використанні cin. [вирішено]

Хочу передати дані з одної програми в іншу через стандартні потоки cin cout.
Написав тестову віконну прогу для передачі і тестову консольку для прийому/опрацювання/віддачі даних.
Але частина даних до консольки десь губиться по дорозі.
Прошу порад де копати.

void MainWindow::on_pushButton_clicked() {
    connect (process, SIGNAL(finished(int)), this, SLOT(printOutput()));
    connect (process, SIGNAL(finished(int)), this, SLOT(printError()));
    QFile *file = new QFile("D:/Yarko/c++/KGV/KGV/main.cpp"); //фізичний розмір 2161 байт
    file->open(QIODevice::ReadOnly);
    char buf[2500]; 
    file->read(buf, 2500); 
    qint64 size = file->size(); //2161. значення size коректне
    process->start("D:/Yarko/c++/KGV/build-KGVTest/debug/KGVTest.exe");
    process->write(buf, size);
    process->closeWriteChannel();
}
void MainWindow::printOutput() {
    QByteArray byteArray = process->readAllStandardOutput(); //приходить лише 1535 байт
    ui->plainTextEdit_2->appendPlainText(QString(byteArray));
}
void MainWindow::printError() {
    QByteArray byteArray = process->readAllStandardError(); //приходить стрічка "1535"
    ui->plainTextEdit_3->appendPlainText(QString(byteArray));
}
int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    char buf[2500];
    int i = 0;
    char c;
    while (cin.good()) {
        cin >> c;
        if (c == ' ') cerr << 's'; //перевірка чи символ - пропуск
        buf[i] = c;
        ++i;
    }
    cout.write(buf, i);
    cerr << i;
    return 0;
}

Як мінімум з потоку не читаються пропуски і \r\n.
p.s. сигнал QProcess::bytesWritten(qint64) показує коректну кількість записаних байт

2 Востаннє редагувалося yarko (06.02.2015 15:56:17)

Re: Частина даних пропадає при використанні cin. [вирішено]

Використав getchar() з <stdio.h> замість cin.

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    int ch;
    int i = 0;
    while ((ch = getchar()) != EOF) {
        putchar(ch);
        ++i;
    }
    cerr << i;
    return 0;
}

Результат кращий, але все одно '\r' не читаються.
Мені потрібно прочитати всі дані без винятків. Ідеї?

3

Re: Частина даних пропадає при використанні cin. [вирішено]

Символи \r, \n (окрема історія з табами і пробілами) у cin сигналізують про завершення вводу. Спробуйте потестити без указаних символів.
Байти і символи - не тотожні поняття.

4 Востаннє редагувалося yarko (06.02.2015 19:20:05)

Re: Частина даних пропадає при використанні cin. [вирішено]

Я не можу тестувати з винятками, інакше вся робота коту під хвіст.
Може хтось працював з іншими функціями читання даних з вхідного потоку?

5

Re: Частина даних пропадає при використанні cin. [вирішено]

yarko написав:

Я не можу тестувати з винятками, інакше вся робота коту під хвіст.
Може хтось працював з іншими функціями читання даних з вхідного потоку?

є збочений варіант, base64, base85 та їм подібні.

6

Re: Частина даних пропадає при використанні cin. [вирішено]

Chemist-i написав:
yarko написав:

Я не можу тестувати з винятками, інакше вся робота коту під хвіст.
Може хтось працював з іншими функціями читання даних з вхідного потоку?

є збочений варіант, base64, base85 та їм подібні.

+1
У випадку з проблемними символами потрібно кодування-декодування у щось портабельне.

7 Востаннє редагувалося yarko (07.02.2015 18:00:12)

Re: Частина даних пропадає при використанні cin. [вирішено]

Символ \r фізично хоч передається у програму, якщо запустити командною стрічкою типу
test.exe < 1.cpp
чи відсівається ще до передачі?

base 64 підійде у випадку, коли дані в програму передаються лише з іншої програми.
Я не бачу можливості як це застосувати у випадку запуску програми з терміналу скажімо (приклад вище)


p.s. От блін. Той же getchar під KUbuntu спокійно читає все, включно з \r, наче нічого і не сталося.

8

Re: Частина даних пропадає при використанні cin. [вирішено]

Схоже, це пов'язано з особливостями передачі нового рядка в DOS/Windows (\r\n) та *nix (\n). Текстовий та двійковий режим роботи з файлами можуть відрізнятися цим — у програмах під Windows у текстовому режимі робиться корекція переносу рядків, щоб для програми \r\n виглядало як \n. Як можна cin зробити з «текстового» «бінарним» — гугліть...

Подякували: yarko1

9 Востаннє редагувалося yarko (09.02.2015 16:04:35)

Re: Частина даних пропадає при використанні cin. [вирішено]

Нарешті...

Окремо для вінди доведеться додати конструкцію

#include <io.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
    ...
    _setmode(_fileno(stdin), _O_BINARY);
    ...

Читати потрібно з допомогою cin.get() без використання порівняння на EOF, бо якщо серед даних зустрінеться значення -1, то воно сприйметься як ознака кінця, а не як дані.

    char c;
    int i = 0;
    c = cin.get();
    while (cin.good()) {
        ++i;
        c = cin.get();
    }
Подякували: koala1