1296 / 469 / 151
Регистрация: 24.08.2011
Сообщений: 2,249
1

Не открывается файл [WinAPI Handle]

08.01.2015, 17:28. Показов 1593. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Ввожу имя существующего файла, но на строке 86 происходит выход из функции, т.е. файл не открывается. Помогите пожалуйста.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <locale.h> // для возможности вывода кириллицы
#include <stdio.h> // для printf/scanf
#include <stdlib.h> // для system
#include <string.h>
#include <Windows.h>
using namespace std;
 
struct Queue
{
    char * data;    //указатель на данные
    Queue * next;   //указатель на следующий элемент очереди
};
 
void Put(Queue** queue, char* data) // поместить данные в конец очереди
{
    Queue *back, *newdata;
 
    newdata = (Queue*)malloc(sizeof(Queue));
    newdata->data = (char*)malloc(strlen(data)+1);
    strcpy(newdata->data, data);
    newdata->next = NULL;
    if (*queue == NULL) // если очередь пуста
        *queue = newdata; // то просто запоминаем новый элемент как первый
    else
    {
        for (back = *queue; back->next != NULL; back = back->next); // проматываем до конца очереди
        back->next = newdata; // добавляем новый элемент в конец
    }
}
 
char* Get(Queue** queue) // извлечь данные из начала очереди (при этом элемент удаляется из очереди)
{
    if (queue == NULL)
        return NULL;
 
    char *firstdata = (*queue)->data; // запоминаем адрес строки первого элемента
    Queue *tmp = (*queue); // запоминаем адрес первого элемента
 
    *queue = (*queue)->next; // второй становится первым
    free(tmp); // освобождаем память из под старого первого элемента (память из под строки не освобождается)
 
    return firstdata; // возвращаем указатель на строку
}
 
void PrintQueue(Queue* queue) // вывод на экран содержимого очереди
{
    Queue *cur;
    
    for (cur = queue; cur != NULL; cur = cur->next)
        printf("\"%s\"\n", cur->data);
}
 
void FreeQueue(Queue **queue) // освобождение памяти из под очереди
{
    Queue *tmp;
    while (*queue != NULL)
    {
        free((*queue)->data);
        tmp = *queue;
        *queue = (*queue)->next;
        free(tmp);
    }
}
 
void WriteQueue(char * fname, Queue * pque) // запись очереди в файл
{
    HANDLE fout = CreateFile((LPCWSTR)fname, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    // CreateFile подробнее: [url]http://www.vsokovikov.narod.ru/New_MSDN_API/Menage_files/fn_createfile.htm[/url]
    Queue *cur;
    unsigned nsuccess;
    
    for (cur = pque; cur != NULL; cur = cur->next)
    {
        WriteFile(fout, cur->data, strlen(cur->data), (LPDWORD)&nsuccess, NULL);
        // WriteFile(идентификатор_файла, адрес_начала_данных, количество_записываемых байтов, количество_успешно_записанных_байтов, дескриптор_защиты(у нас нет защиты))
        WriteFile(fout, "\n", 1, (LPDWORD)&nsuccess, NULL);
    }
 
    CloseHandle(fout);
}
 
void ReadQueue(char * fname, Queue ** pque) // чтение очереди из файла
{
    HANDLE fin = CreateFile((LPCWSTR)fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (fin == INVALID_HANDLE_VALUE)
        return;
    char *s = (char*)malloc(500), *ch = (char*)malloc(2);
    unsigned nsuccess;
 
    ch[1] = '\0'; // ставим символ конца строки, чтобы можно было конкатенировать эту строку с другой без ошибок
    FreeQueue(pque); // чистим очередь, если она вдруг не пуста
    while (true)
    {
        strcpy(s, ""); // очищаем строку
        while (true)
        {
            ReadFile(fin, ch, 1, (LPDWORD)&nsuccess, NULL);
            // ReadFile(идентификатор_файла, адрес_начала_области_памяти, количество_байтов, количество_считанных_байтов, дескриптор_защиты(у нас нет защиты))
            if (ch[0] != EOF && ch[0] != '\n') // если не встретили конец файла или конец строки
                strcat(s, ch); // присоединяем символ к строке
            else
                break;
        }
        if (strcmp(s, "") != 0) // если строка не пуста
            Put(pque, s); // заталкиваем строку в очередь
    }
 
    CloseHandle(fin);
}
 
void main()
{
    char *s = (char*)malloc(50);
    unsigned n, i;
    Queue *begin = NULL;
    setlocale(LC_ALL, "rus"); // переключаем на вывод кириллицы
 
    printf("Полный путь к файлу, в котором содержится набор строк для очереди: ");
    gets(s);
    ReadQueue(s, &begin);
 
    printf("\nСодержимое очереди:\n");
    PrintQueue(begin);
 
    printf("\nСколько элементов достать из очереди: ");
    scanf_s("%u", &n);
    for (i = 0; i < n; i++)
    {
        s = Get(&begin);
        if (s != NULL)
        {
            printf("\"%s\"\n", s);
            free(s);
        }
        else
            break;
    }
 
    printf("\nНовое содержимое очереди:\n");
    PrintQueue(begin);
 
    printf("Полный путь к файлу, куда будет записано новое содержимое очереди: ");
    gets(s);
    WriteQueue(s, begin);
    printf("Содержимое сохранено в файл %s\n", s);
    
    FreeQueue(&begin);
    free(s);
    system("pause");
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.01.2015, 17:28
Ответы с готовыми решениями:

handle,winapi
Всем привет.Порекомендуйте литературу по Winapi,handle и т.п.

Access 2003 .mdb файл не открывается с ярлыка на него на файл сервере, но открывается если снач запус Access
Вирусов нет. Установлены все обновления Windows, Office. Есть сеть состоящая из 6...

Как выбрать окно, если его handle не совпадает с handle процесса?
Добрый день! Задача на первый взгляд довольно простая: выбрать окно программы, переместить его в...

Что означает выражение HANDLE hWritePipe = (HANDLE)atoi(argv[1]);
К тому же у меня нет 1-го. только нулевой

3
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
08.01.2015, 17:47 2
Лучший ответ Сообщение было отмечено MayaNash как решение

Решение

C++
1
2
3
void WriteQueue(char * fname, Queue * pque) // запись очереди в файл
{
    HANDLE fout = CreateFile((LPCWSTR)fname, ...
LPCWSTR - это указатель на wchar-строку (2 байта на символ), а fname -
это char-строка (1 байт на символ). Поэтому, если проект настроен на
использование Unicode, CreateFile (а точнее, CreateFileW) и обламывается.
1
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
08.01.2015, 17:50 3
Вы принимаете имя файла как const char*, а потом пытаетесь запихнуть его в функцию как lpwcstr (const wchar_t*) с помощью принудительного каста указателя.
1
1296 / 469 / 151
Регистрация: 24.08.2011
Сообщений: 2,249
08.01.2015, 19:27  [ТС] 4
Спасибо, а как быть с EOF? Он не распознается в char, как тогда считывать, чтобы он был виден?

Добавлено через 1 час 1 минуту
Поняла - нужно проверять количество успешно считанных символов
0
08.01.2015, 19:27
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.01.2015, 19:27
Помогаю со студенческими работами здесь

Из командной строки файл вообще не открывается а если открыть через проводник, то открывается и сразу вылетает
masm model small stack 256 .data per_1 db 23 per_2 dw 9856 per_3 dd 9875645 per_4 dw...

В чем различия дескриптора,полученного из WinAPI функций и дескриптора, полученного из свойства Handle в классе Process?
Можно ли использовать дескриптор окна,полученный с помощью свойства Handle в классе Process для...

Как перемотать HANDLE hFile на начальный файл в директории?
как перемотать HANDLE hf на начальный файл в директории так как во второй раз когда пользуюсь...

Получить handle процесса, который использует файл в данный момент
собственно, вопрос в этом. не нашел ничего в тырнете по этому поводу


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru