Не понимаю один момент, который заключается в следующем: мне необходимо получить данные из двоичного файла (.bin), куда раннее были записаны данные в виде двух строчек string и двух чисел int (структуры, в общем), при исполнении кода:
void Opf() {
if ((fl = fopen(flName, "rb")) == NULL) {
cout << "Ошибка открытия файла..." << endl;
exit(1);
}
nst = 0;
TBook book;
while (true)
{
int nwrt = fread(&book, sizeof(TBook), 1, fl);
if (nwrt != 1) { break; }
books[nst] = book;
cout << books[nst].name << " " << " " << books[nst].author << " "
<< books[nst].yearof << " " << books[nst].pages << endl;
nst++;
}
fclose(fl);
}
Выдаёт следующую ошибку:
Вызвано необработанное исключение: нарушение доступа для чтения.
**_Pnext** было 0x61747353.
В чём может быть ошибка или же как можно это обойти?
Задача: По данным n отрезкам необходимо найти множество точек минимального размера, для которого каждый из отрезков содержит хотя бы одну из точек.
В первой строке дано число 1≤n≤100 отрезков. Каждая из последующих n строк содержит по два числа 0≤l≤r≤109, задающих начало и конец отрезка. Выведите оптимальное число m точек и сами m точек. Если таких множеств точек несколько, выведите любое из них.
Мое решение:
void swap(int *a1, int *a2, int M);
void sort(int **a, int N, int M);
void greedy(int **a, int *x, int N);
int main()
{
int **a;//двумерный массив отрезков
int N;
int M=2;
int *x;//одномерный массив точек
cout << "Enter N: "; //ввод количества отрезков
cin>>N;
x = new int[N]; //инициализация массива, который потом станет массивом точек
for (int i=0; i<N; i++)
x[i]=0;
a = new int *[N];
for (int i = 0; i < N; i++)
a[i] = new int [M];
//ввод концов отрезков
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
cin >> a[i][j];
}
}
//вывод до сортировки
cout <<endl << "Before sorting:" << endl;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
cout << std::setw(3) << a[i][j] << " ";
cout << endl;
}
sort(a, N, M);//сортировка массива
//вывод после сортировки
cout << endl << "After sorting:" << endl;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
cout << setw(3) << a[i][j] << " ";
cout << endl;
}
//вызов функции с жадным алгоритмом
greedy(a,x, N);
for (int i=0; i<=N; i++)
cout<<x[i]<<' ';
system("pause");
return 0;
}
void swap(int *a1, int *a2, int M)//меняет 2 строки местами
{
for (int i = 0; i < M; i++)
{
int temp = a1[i];
a1[i] = a2[i];
a2[i] = temp;
}
}
void sort(int **a, int N, int M)//сортировка пузырьком отрезков по правой точке
{
for (int i = 0; i < N; i++)
for (int j = N - 1; j > i; j--)
if (a[j - 1][1] >a[j][1])
swap(a[j - 1], a[j], M);
}
void greedy(int **a, int *x, int N)
{
int i=0;
int k=0;
while (i<=N)
{
x[k]=a[i][1];
i++;
while ((x[k]>=a[i][0]) && (x[k]<=a[i][1]))
{i++;}
k++;
}
}
Но программа падает с ошибкой: Нарушение прав доступа при чтении. Может, кто видит, почему?
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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
#include <iostream> #include <ctime> //#include <stdio.h> using namespace std; struct Node { int key; struct Node* next; struct Node* prev; }; class List { private: int key = 0; size_t size = 0; Node* head = NULL; Node* tail = NULL; public: List() { head = tail; size; cout << "List is created!" << endl; } List (int a) { int elementov{}, N{}, K{}, tmpHand[100] = {}, tmpRand{}; if (a == 2) Rand(); if (a == 1) Hand(); cout << "Elements are created!" << endl; } ~List() { Node* current = head; while (current != 0) { Node* next = current->next; delete current; current = next; } head = 0; cout << "Destructor deleted list!" << endl; } Node* Get_node(int number); Node* Create_node(int key); void Insert(const int key); void Print(); void Pop_front(); void Swap(Node* const before1, Node* const before2); void Append(const int num); int Get_Value(int N); void Inverse_sublist(const int K, const int N); void Hand(); void Rand(); }; // получение адреса элемента по его порядковому номеру (счет от 1 ) Node* List::Get_node(int number) { int i; Node* scan = this->head; if (scan == nullptr) return 0; for (i = 1; i < number; i++) scan = scan->next; return scan; } void List::Hand() { int tmpHand[100]{}, elementov{}; for (int i = elementov; i > 0; i--) { cout << "Введите элемент списка: n" << endl; cin >> tmpHand[i]; Append(tmpHand[i]); } } void List::Rand() { int tmpRand{}, elementov{}; for (int i = 0; i < elementov; i++) { tmpRand = rand() % 100; Insert(tmpRand); } } Node* List::Create_node(int key) { Node* new_node = (Node*)malloc(sizeof(Node)); if (new_node) { new_node->key = key; new_node->next = NULL; } return new_node; } // вставка элемента в начало списка void List::Insert(const int key) { Node* add = Create_node(key); if (this->head != NULL) add->next = this->head; this->head = add; this->size++; } // вывод списка на экран void List::Print() { Node* scan = this->head; printf("List items: "); while (scan) { printf("%d -> %p ", scan->key, scan->next); scan = scan->next; } } // удаление элемента из начала ЛОС void List::Pop_front() { Node* del = this->head; this->head = del->next; free(del); this->size--; } // обмен местами двух элементов ЛОС void List::Swap(Node* const before1, Node* const before2) { Node* self1, * self2, * tmp; // before1 = Get_node(list, N1-1); // before2 = Get_node(list, N2-1); self1 = before1->next; self2 = before2->next; tmp = before1->next; before1->next = before2->next; before2->next = tmp; tmp = self1->next; self1->next = self2->next; self2->next = tmp; } void List::Append(const int num) { Node* const add_node = Create_node(num); this->size++; // если список пуст if (!this->head) { this->head = this->tail = add_node; } this->tail->next = add_node; this->tail = add_node; } int List::Get_Value(int N) { Node* tmp = Get_node(N); return tmp->key; } void List::Inverse_sublist(const int K, const int N) { int i, j; Node* left = Get_node(K - 1); if (left == nullptr) return; Node* right; for (i = 0; i < N / 2; i++) { //right = left->next;//может быть сделать так? right = left; for (j = 0; j < (N - 2 * i) && right->next != nullptr; j++) right = right->next; Swap(left, right); left = left->next; } } //-------------------------------------------------------------- int main(int argc, char* argv[]) { //logo(); printf("В списке целых ненулевых элементов инвертировать K элементов начиная с Nn"); srand((unsigned int)time(NULL)); int i = 0, tmpRand = 0; int tmpHand[100] = {}; //ClassList::Node* node_a = 0; //ClassList::Node* node_b = 0; FILE* config; char Conf_Name[50] = "testo.cfg", buffer[100]; int sposob{}, elementov{}, K{}, N{}; if ((config = fopen(Conf_Name, "r")) == NULL) { puts("Config file error!!!"); puts("Press Enter!!!"); std::cin.get(); exit(0); } fgets(buffer, 80, config); if (!strstr(buffer, "#!MYCONFIG")) { puts("Config file error!!!"); puts("Press Enter!!!"); std::cin.get(); fclose(config); exit(0); } while (true) { fgets(buffer, 80, config); if (feof(config))break; if (buffer[0] == '#')continue; if (buffer[0] == '!') { puts(buffer); continue; } if (strstr(buffer, "sposob=")) { sposob = atoi(buffer + strlen("sposob=")); continue; } if (strstr(buffer, "elementov=")) { elementov = atoi(buffer + strlen("elementov=")); continue; } if (strstr(buffer, "K=")) { K = atoi(buffer + strlen("K=")); continue; } if (strstr(buffer, "N=")) { N = atoi(buffer + strlen("N=")); continue; } } puts("=============Result of parsing config file ========"); cout << "sposob = " << sposob << endl; cout << "elementov = " << elementov << endl; cout << "K = " << K << endl; cout << "N = " << N << endl; cout << "Press Enter!!!" << endl; std::cin.get(); fclose(config); if (elementov > 20) { printf("Слишком много элементов в списке! Выход...n"); return 1; } if (sposob != 1 && sposob != 2) { printf("Некорректный способ заполнения спискаn"); return 1; } if (K + N > elementov) { printf("Некорректные данные в конфигурационном файле (N + K > элементовn)"); return 1; } if (N > elementov) { printf("Некорректные данные: количество инвертируемых элементов больше чем элементов в спискеn"); return 1; } // "объект" ЛОС с инициализацией List list(sposob); list.Print(); list.Inverse_sublist(K, N); list.Print(); } |
I am currently working on the BlackJack project, but there is an error showing «exception Unhandled: Unhandled exception thrown: read access violation. this was 0x4.». I am not quite sure which part I did wrong, and the program sometimes runs normally sometimes shows that exception. In draw_card function, it returns a value of a random number. For example: if we get 13, the value will be 10. It also returns the name of the card and the type of the card such as 13 corresponds to king.
int main()
{
srand(time(0));
unsigned bet;
int player = 0 , dealer = 0;
string card , type;
cout << "You have $100. Enter bet: ";
cin >> bet;
cout << "Your cards are:" << endl;
player += draw_card(card, type, player);
cout << " "+card + " of " + type << endl;
player += draw_card(card, type, player);
cout << " " + card + " of " + type << endl << endl << endl;
}
int draw_card(string& card, string& type, int drawer_points) {
int randomNumber; //between 1 and 13
int suite; //between 1 and 4 to determine the suite of the card.
randomNumber = rand() % 13 + 1;
suite = rand() % 4 + 1;
card = getRank(randomNumber);
type = getSuit(suite);
if (randomNumber == 13 || randomNumber == 12 || randomNumber == 11) {
return 10;
}else if (randomNumber == 1) {
int ace1 = 21 - (drawer_points + 1);
int ace2 = 21 - (drawer_points + 11);
return ace1 < ace2 ? 1 : 11;
}
else
{
return randomNumber;
}
}
string getSuit(int suit) {
switch (suit)
{
case 0:
return "spades";
break;
case 1:
return "clubs";
break;
case 2:
return "diamonds";
break;
case 3:
return "hearts";
break;
default:
break;
}
}
string getRank(int rank) {
switch (rank)
{
case 13:
return "King";
break;
case 12:
return "Queen";
break;
case 11:
return "Jack";
break;
case 1:
return "Ace";
break;
case 2:
return "Two";
break;
case 3:
return "Three";
break;
case 4:
return "Four";
break;
case 5:
return "Five";
break;
case 6:
return "Six";
break;
case 7:
return "Seven";
break;
case 8:
return "Eight";
break;
case 9:
return "Nine";
break;
case 10:
return "Ten";
break;
default:
break;
}
user438383
5,5868 gold badges28 silver badges41 bronze badges
asked Jan 18, 2022 at 18:12
5
You generate
suite = rand() % 4 + 1;
This is a random number between 1 and 4 inclusive.
You then call
getSuit(suite);
But getSuit
only has switch branches for values between 0 and 3 inclusive:
switch (suit)
{
case 0:
return "spades";
break;
case 1:
return "clubs";
break;
case 2:
return "diamonds";
break;
case 3:
return "hearts";
break;
default:
break;
}
Not returning a value from a function that is declared to return a value is undefined behaviour.
answered Jan 18, 2022 at 18:27
konsolaskonsolas
1,00111 silver badges24 bronze badges
A few functions like getSuit
and getRank
in your code don’t return a value if only the default case of their switch
statement is executed.
You can return an empty string in the default cases:
default:
return ""; // empty string
And in the call site, check to see if the returned value is empty using the empty
function.
Another way is to use std::optional<T>
like below:
std::optional<string> getSuit( const int suit )
{
switch (suit)
{
case 0:
return "spades";
case 1:
return "clubs";
case 2:
return "diamonds";
case 3:
return "hearts";
default:
return { }; // empty optional
}
}
And in the call site:
std::optinal<std::string> type { getSuit(suite) };
if ( type ) // if optional has value
{
// extract and use the value inside of optional
type.value( );
}
Keep in mind that if the optional does not have a value, using value()
will throw. You can use value_or()
instead which does not throw.
answered Jan 18, 2022 at 18:28
digito_evodigito_evo
3,1542 gold badges13 silver badges39 bronze badges
2
#c #exception #visual-studio-2019
#c #исключение #visual-studio-2019
Вопрос:
Я не понимаю, что происходит.
Я создал программу для получения ввода символа и вывода его обратно. Я получаю это исключение каждый раз, когда нажимаю enter для ввода значения в программу:
Генерируется необработанное исключение: нарушение доступа для чтения. this->_format_it было 0x38.
Я попробовал большое количество входных данных, и кажется, что независимо от того, что я ввожу, это приведет ко мне. На самом деле, это почти точно тот код, который мне дал мой колледж
Вот код:
// Card Value
// cardValue.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
char rank = 'c';
printf("Enter the card rank : ");
scanf("%c", amp;rank);
printf(rank);
return 0;
}
Удаление оператора адреса приведет к другому исключению:
Необработанное исключение в 0x79B498F1 (ucrtbased.dll ) в Карточке Decks.exe : 0xC0000005: местоположение записи с нарушением доступа 0x00000063.
Комментарии:
1. Какая перегрузка
printf
не требует ничего, кроме achar
? Можете ли вы указать нам на документацию для этого?2.
printf(rank);
недопустимо, посколькуprintf()
не принимает ни одногоchar
в качестве входных данных. 1-й параметр должен быть achar*
, так что, возможно, вы на самом деле использовалиprintf(amp;rank);
вместо этого? Это также было бы недопустимо, поскольку не является допустимойamp;rank
строкой с нулевым завершением. Вместо этого вам нужно использоватьprintf("%c", rank);
.3. C в любом случае не поддерживает перегрузки.
4. …. или исключения.
5. Обратите внимание, что
#define _CRT_SECURE_NO_WARNINGS
это не подавляет то предупреждение, которое вы должны были видеть о переходеchar
printf
.
Ответ №1:
printf()
первым аргументом должен быть указатель на строку формата, а не символ. Вы могли бы сделать
printf("%c", rank);
Комментарии:
1. Это дает мне совершенно другую ошибку.
2. Необработанное исключение в 0x79B498F1 (ucrtbased.dll ) в Карточке Decks.exe : 0xC0000005: местоположение записи с нарушением доступа 0x00000063.
3. @CarsonFujita-Тернбулл, потому что вы «удалили адрес оператора» без предупреждения и без какой-либо причины для этого
Ответ №2:
printf(rank);
неверно, поскольку printf()
не принимает ни одного char
такого ввода.
В C этот код вообще не будет компилироваться. Но в C компилятор неявно преобразует целочисленное значение в указатель и char
является целочисленным типом.
Ошибка нарушения доступа для чтения жалуется на считываемый адрес памяти 0x38
. 0x38
это код ASCII для символа '8'
, это значение, которое вы вводите?
1-й параметр printf()
должен быть char*
указателем на строку формата с нулевым завершением, например:
printf("%c", rank);
Все примеры в коде, который вам дал ваш колледж, представлены в этой аналогичной форме.
Если вы удалите amp;
on scanf("%c", amp;rank)
вызов (почему?), Вы получите запись с нарушением доступа к адресу памяти 0x63
, потому что значение rank
неявно преобразуется как есть в указатель. 0x63
это код ASCII для символа 'c'
, который вы инициализируете rank
.
Комментарии:
1. Да, я идиот. Я заменил его на » printf («% c», rank); » и исправил это