I need help with my C program


#1

Hello guys, i made this program a few minutes ago and the compiler doesnt give any error but when i start the program it crashes. Can someone help me?

#include <stdio.h>

int main() {

int numeroAluno, numeroUCs, melhorAluno, alunosProcessados = 0, aproveitamentoAOC = 0, aproveitamentoOE = 0, aproveitamentoAP = 0, aproveitamentoOLP = 0, aproveitamentoMD = 0, i;
float mediaUCs = 0, mediaAlunos = 0, melhorMedia = -1, notaUC = 0;
char nomeUC = ' ';

// Leitura do primeiro número de aluno
do {
	printf("Introduza o numero de aluno (0 para sair): ");
	scanf("%d", &numeroAluno);
} while (numeroAluno < 0);


// Caso o número seja válido (!=0), entra no ciclo
while (numeroAluno != 0) {
	
	// Lê quantas UCs fez o aluno
	do {
		printf("Quantas UCs fez o aluno %d (entre 1 e 5)? ", numeroUCs);
		scanf("%d", &numeroUCs);			
	} while (numeroUCs > 5 || numeroUCs < 1); // Só aceita valores entre 1 e 5, inteiros
	
	// Executa x vezes
	for (i = 1; i <= numeroUCs; i++) {
		
		do {
			printf("Qual das UCs?\n(A)lgoritmia, A(R)quitetura, (O)ficinas, (M)atematica e Or(G)anizacao\n");
			scanf("%c",&nomeUC);
			nomeUC = toupper(nomeUC);
		} while (strcmp(nomeUC, "A") != 0 || strcmp(nomeUC, "R") != 0 || strcmp(nomeUC, "O") != 0 || strcmp(nomeUC, "M") != 0 || strcmp(nomeUC, "G") != 0);
		
		// Lê a nota
		do {
			printf("Com que nota? ");
			scanf("%d", &notaUC);
		} while (notaUC < 0 || notaUC > 20); // Só aceita entre 0 e 20
		
		// Caso a nota seja positiva,
		if (notaUC > 9.5) {
			
			// Verifica a que UC se refere e
			if (strcmp(nomeUC, "A") != 0) aproveitamentoAP++;  // Incrementa o aproveitamento de Algoritmia
			else if (strcmp(nomeUC, "R") != 0) aproveitamentoAOC++; // Incrementa o aproveitamento de Arquiteturas
				 else if (strcmp(nomeUC, "O") != 0)  aproveitamentoOLP++; // Incrementa o aproveitamento de Oficinas
					  else if (strcmp(nomeUC, "M") != 0) aproveitamentoMD++;// Incrementa o aproveitamento de Matemática
					  	   else aproveitamentoOE++; // Incrementa o aproveitamento de Organização
			}
		}
		
		// Acrescenta a nota ao valor da média
		mediaUCs += notaUC;
		
		// Faz reset às variáveis
		nomeUC = ' ';
		notaUC = 0; }
		
	// Calcula a média do aluno
	mediaUCs = mediaUCs / numeroUCs;
	
	// Acrescenta a média do aluno à média geral
	mediaAlunos += mediaUCs;
	
	// Verifica se se trata do aluno com melhor média
	if (mediaUCs > melhorMedia) {
		melhorMedia = mediaUCs;
		melhorAluno = numeroAluno; }
		
	// Imprimir informacao do aluno
	printf("O aluno %d concluiu %d UCs com media de %f valores.\n\n", numeroAluno, numeroUCs, mediaUCs);
	
	// Faz reset às variáveis
	mediaUCs = 0;
	numeroAluno = 0;
	numeroUCs = 0;
	
	// Incrementa o número de alunos processados
	alunosProcessados++;
	
	// Lê o próximo aluno
	do {
		printf("Introduza o numero de aluno (0 para sair): ");
		scanf("%d", &numeroAluno);
	} while (numeroAluno < 0);


// Imprime todas as informações
// Se não tiverem sido inseridos alunos

if (alunosProcessados == 0) {
 printf("Não foram inseridos dados."); 
 }
else (alunosProcessados != 0); {

	mediaAlunos = mediaAlunos / alunosProcessados;
	printf("**********\nConsideramos %d alunos.\n", melhorAluno);
	printf("O aluno %d tem a melhor media, com $f.2 valores.", melhorMedia, alunosProcessados);
	printf("Media de notas foi %f.2 valores.\n", mediaAlunos);
	printf("**********\nUnidades Curriculares e numero de alunos com aproveitamento.\nAlgoritmia %d alunos.\nArquitetura %d alunos.\nOficinas %d alunos.\nMatematica %d alunos.\nOrganizacao %d alunos.\n",
		aproveitamentoAP, aproveitamentoAOC, aproveitamentoOLP, aproveitamentoMD, aproveitamentoOE); 

}
return 0;

}

#2

Hi your problem might be numeroAluno does not have a value you just define it so its null and I’m not sure a defined but valueless can campare to 0 I’m hope this helps.


#3

Can you like, copy and change. Because i didnt quite understood :confused:


#4

You say that there are no errors, but what about warnings? Here’s what gcc (version 7.2.1) has to say while compiling your code:

$ gcc -Wall main.c
main.c: In function ‘main’:
main.c:30:26: warning: implicit declaration of function ‘toupper’ [-Wimplicit-function-declaration]
                 nomeUC = toupper(nomeUC);
                          ^~~~~~~
main.c:31:22: warning: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration]
             } while (strcmp(nomeUC, "A") != 0 || strcmp(nomeUC, "R") != 0 || strcmp(nomeUC, "O") != 0 || strcmp(nomeUC, "M") != 0 || strcmp(nomeUC, "G") != 0);
                      ^~~~~~
main.c:36:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘float *’ [-Wformat=]
                 scanf("%d", &notaUC);
                        ~^   ~~~~~~~
                        %e
main.c:93:29: warning: statement with no effect [-Wunused-value]
     else (alunosProcessados != 0); {
          ~~~~~~~~~~~~~~~~~~~^~~~~
main.c:93:5: warning: this ‘else’ clause does not guard... [-Wmisleading-indentation]
     else (alunosProcessados != 0); {
     ^~~~
main.c:93:36: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘else’
     else (alunosProcessados != 0); {
                                    ^
main.c:97:26: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat=]
         printf("O aluno %d tem a melhor media, com $f.2 valores.", melhorMedia, alunosProcessados);
                         ~^
                         %f
main.c:97:16: warning: too many arguments for format [-Wformat-extra-args]
         printf("O aluno %d tem a melhor media, com $f.2 valores.", melhorMedia, alunosProcessados);
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


#5

You can also use valgrind with --tool=memcheck to find out that you’re making use of an uninitialized variable at line 20

$ gcc -g main.c && valgrind --tool=memcheck ./a.out
==17480== Use of uninitialised value of size 8
==17480==    at 0x4E8321B: _itoa_word (in /usr/lib/libc-2.26.so)
==17480==    by 0x4E8698F: vfprintf (in /usr/lib/libc-2.26.so)
==17480==    by 0x4E8E9C5: printf (in /usr/lib/libc-2.26.so)
==17480==    by 0x1088B1: main (main.c:20)

          < I cut out the rest of the output >

That variable did end up with the value 0 even though it wasn’t initialized, but that’s just coincidence, that location in memory just happened to be set to 0, it’s not something you did.

And then, after having fixed the memory issues and warnings, only then would you fire up a debugger and watch where the crash happens:

$ gcc -g main.c && gdb a.out
(gdb) run
Starting program: /tmp/derp/eoanuth/a.out                                                                                                                                                                          
Introduza o numero de aluno (0 para sair): 3                                                                                                                                                                       
Quantas UCs fez o aluno 0 (entre 1 e 5)? 3                                                                                                                                                                         
Qual das UCs?                                                                                                                                                                                                      
(A)lgoritmia, A(R)quitetura, (O)ficinas, (M)atematica e Or(G)anizacao

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7aaecda in __strcmp_sse2_unaligned () from /usr/lib/libc.so.6                                                                                                                                           
(gdb) where                                                                                                                                                                                                        
#0  0x00007ffff7aaecda in __strcmp_sse2_unaligned () from /usr/lib/libc.so.6                                                                                                                                       
#1  0x000055555555492f in main () at main.c:31
(gdb) select-frame 1                                                                                                                                                                                               
(gdb) info locals                                                                                                                                                                                                  
numeroAluno = 3
numeroUCs = 3
melhorAluno = 21845
alunosProcessados = 0
aproveitamentoAOC = 0
aproveitamentoOE = 0
aproveitamentoAP = 0
aproveitamentoOLP = 0
aproveitamentoMD = 0
i = 1
mediaUCs = 0
mediaAlunos = 0
melhorMedia = -1
notaUC = 0
nomeUC = 10 '\n'
(gdb) 

Which tells you it’s line 31 in your code, and that it’s crashing inside strcmp, so then you would look closer at how you’re using strcmp, because most likely it is crashing due to invalid input (the arguments to strcmp)

strcmp(nomeUC, "A")

As seen from the debugger, nomeUC has the value '\n', so:

strcmp('\n', "A")

Which isn’t how to use strcmp, and fixing that most likely lets the program continue.

The reason for taking care of warnings and memory issues first is because they’re easy to fix, they’re easy to find, they may be the cause of the crash (it might just go away after fixing that stuff), and they might make it much harder to debug your crash later. Plenty of reasons to take care of them first, it’s basic sanity-checking. (for example, one of the warnings was that you hadn’t included strcmp, so that sure seems like a good thing to do before debugging what you’re doing with strcmp)