Dpry12 Dpry12 - 1 month ago 7
C Question

C: Incorrect characters are being printed, suspected mem. issue

I am running into something interesting, where weird characters are getting printed instead of what I am expecting. It was not doing this earlier, but I started playing around with the fgets and sscanf and now it will not return to the way it was. I'm guessing I corrupted memory somewhere, or left something in the stdin buffer, but not really sure. Any ideas?

What I am expecting:

***************************************************************************
* *
* *
* 1) What char for border? *
* 2) Add question *
* 3) Remove Question *
* 4) Print last answers *
* 5) Exit *
* *
* *
* *
* *
***************************************************************************


What is actually printing (as you can see, it's printing a funky y and consuming a space):

***************************************************************************
* *
* *
* 1) What char for border? *
* 2) Add question *
* 3) Remove Question *
* 4) Print last answers *
* 5) Exit *
* *
* ΓΏ *
* *
* *
***************************************************************************


Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct f_in{
char outline;
int lines;
int rows;
int num_args;
} F_IN;

typedef struct args_in {
char in_string[20];
int t_format;
} ARGS_IN;

void printInterface(char argQs[5][50], char argChar);

int main(int argv, char** argc){
char defaultQuestions[5][50] = { { "1) What char for border?" }
, { "2) Add question" }
, { "3) Remove Question" }
, { "4) Print last answers" }
, { "5) Exit" } };
int commandEntry, exitFlag, i;
char borderChar = '*', addQ[50], userInp[10];

exitFlag = 1;

while (exitFlag){
printInterface(defaultQuestions, borderChar);

// GET INITIAL INPUT FROM USER
printf("Enter the integer value for the command you wish to select: ");
fgets(userInp, sizeof(userInp), stdin);
// VERIFY INPUT IS VALID
sscanf(userInp, "%d", &commandEntry);
printf("\nYou selected: %s\n", defaultQuestions[commandEntry - 1]);

if (commandEntry == 1){
printf("Please enter the character you wish to be the border: ");
scanf("\n%c", &borderChar);
}
else if (commandEntry == 2){
printf("What question would you like to add? (only enter 50 char max)\n");
fgets(addQ, 50, stdin);
printf("This was your question: %s", addQ);
}
else if (commandEntry == 5){
printf("Goodbye!\n");
exitFlag = 0;
}
}
return 0;

}

void printInterface(char argQs[5][50], char argChar){
int i, j;
int lineCnt = 13;
int borderLen = 75;

for (i = 0; i<100; i++){
printf("\n");
}

for (i = 0; i<lineCnt; i++){

if (i == 0 || i == lineCnt - 1){
for (j = 0; j<borderLen; j++){
printf("%c", argChar);
}
printf("\n");
}

else if (i >= 3 && i <= 10){
printf("%c %s", argChar, argQs[i - 3]);
for (j = 0; j < ((borderLen - strlen(argQs[i - 3]))-6); j++){
printf(" ");
}
printf("%c\n", argChar);
}

else{
for (j = 0; j<borderLen; j++){
if (j == 0){
printf("%c", argChar);
}
else if (j == (borderLen - 1)){
printf("%c\n", argChar);
}
else{
printf(" ");
}
}
}
}

for (i = 0; i<10; i++){
printf("\n");
}

}

Answer

Trick here when debugging always try checking what happens using the first/last indexes. If you check in:

else if (i >= 3 && i <= 10){
    printf("%c    %s", argChar, argQs[i - 3]);
    for (j = 0; j < ((borderLen - strlen(argQs[i - 3]))-6); j++){
        printf(" ");
    }
    printf("%c\n", argChar);
}

argChar has 5 entries, but you are trying to access 8 in argQs[i - 3]) when i=10 (condition is if (i >= 3 && i <= 10)). In C you won't get a fancy IndexOutOfRange error, you will basically access another memory registry in the location BASE_ADDR+8.

In C the terms array and pointer are almost interchangeably since both specify the address of a memory block. Since an array is basically a consecutive block of memory, the name of the array is a pointer to the first element. Example: array[25] is equivalent to *(array + 25) .

Hope helps.