【发布时间】:2021-10-30 03:52:23
【问题描述】:
这个程序正好在 case '2' 的 break 语句上崩溃。没什么大不了的,它可以很好地执行该案例的代码,但是它在break语句上崩溃,这真的很奇怪,程序应该只是恢复循环。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#define nullptr ((void*)0)
typedef unsigned char byte; //Tipo numérico de 8 bits
#define max 255
#define cap 256
typedef struct Elemento Elemento;
struct Elemento {
char* valor;
byte prioridade;
bool isvalid;
};
typedef struct {
short comprimento;
Elemento elementos[cap];
} Lista;
void inicializa (Lista* q) { //1
q->comprimento = 0;
}
void ordena (Lista *q) {
short i;
for (i = 1; i < q->comprimento; i ++) {
Elemento e = q->elementos[i];
short j;
for (j = i - 1;
j >= 0 && q->elementos[j].prioridade < e.prioridade;
j --) {
strcpy(q->elementos[j + 1].valor, q->elementos[j].valor);
q->elementos[j + 1].prioridade = q->elementos[j].prioridade;
}
q->elementos[j + 1] = e;
}
}
void enfileira (Lista* q, Elemento *s, byte p) { //2
if (q->comprimento != cap) {
q->elementos[q->comprimento].valor = (char *) malloc(strlen(s->valor)*sizeof(char));
strcpy(q->elementos[q->comprimento].valor, s->valor);
q->elementos[q->comprimento].prioridade = p;
q->elementos[q->comprimento].isvalid = true;
q->comprimento ++;
if (q->comprimento > 1) ordena(q);
}
}
Elemento primeiro (Lista* q) { //3
Elemento e;
if (q->comprimento != 0) {
e.isvalid = true;
strcpy(e.valor, q->elementos[0].valor);
return e;
}
e.isvalid = false;
return e;
}
Elemento remova (Lista* q) { //4
Elemento e;
if (q->comprimento != 0) {
e.isvalid = true;
strcpy(e.valor, q->elementos[0].valor);
byte i;
for (i = 0; i < q->comprimento - 1; i ++) {
strcpy(q->elementos[i].valor, q->elementos[i + 1].valor);
q->elementos[i].prioridade = q->elementos[i + 1].prioridade;
}
q->comprimento --;
return e;
}
e.isvalid = false;
return e;
}
short comprimento (Lista* q) { //5
return q->comprimento;
}
void reinicializa (Lista* q) { //6
q->comprimento = 0;
}
void finaliza (Lista* q) { //7
}
int main () {
Lista s;
Elemento e; e.valor = nullptr;
char *string = nullptr;
float valor;
byte prioridade;
short buffer_tam, string_tam;
byte input;
do {
printf("operacao: ");
string_tam = getline(&string, &buffer_tam, stdin);
switch (string[0]) {
case '1':
inicializa(&s);
break;
case '2':
string_tam = getline(&e.valor, &buffer_tam, stdin);
e.valor[string_tam - 1] = '\0';
scanf("%hhu", &prioridade);
enfileira(&s, &e, prioridade);
break;
case '3':
printf("%s\n", primeiro(&s).valor);
break;
case '4':
printf("%s\n", remova(&s).valor);
break;
case '5':
printf("%hi\n", comprimento(&s));
break;
case '6':
reinicializa(&s);
break;
case '7':
finaliza(&s);
break;
}
} while (string[0] != '0');
return 0;
}
也许它在其他地方无法重现,所以可能有一个常见的原因导致这种情况发生,但我在谷歌上没有找到关于这个主题的任何内容。
解决方案:当我用 'if' 语句替换 switch 时发生了同样的事情,只要它离开 if 环境就会崩溃。造成这种情况的原因是 getline 和 scanf 的混合,我用另一个 getline 替换了 scanf 以防万一'2'并且它没有崩溃。
【问题讨论】:
-
你怎么知道它在 break 语句上崩溃了?
-
string_tam - 1有什么意义?为什么不string_tam?如果 getline 返回 -1 怎么办? -
它在 break 语句上崩溃了,因为我已经在它上面设置了断点,并且它在 break 之后就崩溃了,真的很奇怪。
-
我没有检查 getline 返回的可能性,我会检查一下,谢谢。
-
"原因是 getline 和 scanf 的混合" ...永远不要混合这两者!!!始终只使用
fgets()(或POSIXgetline())[可能偶尔使用getchar()] 用于用户输入:-)
标签: c crash switch-statement break