'Why is NULL printed here? - C-90

The code:

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

#define N 500
#define M 100

/*Version 1*/
void replace_word(char *word);
void add_new_word_dictionary(void);
void do_nothing(void);
void return_basic(void);
void check_word(void);
void compute_words(void);
void compute_characters(void);
void compute_ch_sp(void);
void compute_num_dif_words(void);
void create_istogram(void);
void save_file(void);
int get_choice(void);
void return_word(void);
void insert_text(int numwords, char matrix[N][M], int posit);

int main() {
    int j;
    int choice = 0;
    char matrix[N][M];
    char word[40] = { "t" };
    while (1) {
        choice = get_choice();
        if (choice == 0) {
            insert_text(M, matrix, 1);
        }
        if (choice == 1) {
            add_new_word_dictionary();
        }
        if (choice == 2) {
            do_nothing();
        }
        if (choice == 3) {
            save_file();
        }
        if (choice == 4) {
            compute_words();
        }
        if (choice == 5) {
            break;
        }
        for (j = 0; j < M; j++) {
            printf("%s", matrix[N][M]);
        }
    }

    printf("\n End of Program \n");
    return 0;
}

void replace_word(char *word) {
    return;
}

void add_new_word_dictionary(void) {
    char word[50] = { "s" };
    printf("\nPlease enter the word\n");
    scanf("\n%s", word);
    printf("Your word is %s", word);
    return;
}

void do_nothing(void) {
    printf("\n do_nothing \n");
    return;
}

void return_basic(void) {
    printf("\n return basic \n");
    return;
}

void check_word(void) {
    printf("\n check word \n");
    return;
}

void compute_words(void) {
    printf("\n compute_words \n");
    return;
}

void compute_characters(void) {
    printf("\n compute characters \n");
}

void compute_ch_sp(void) {
    printf("\n compute_ch_sp \n");
    return;
}

void compute_num_dif_words(void) {
    printf("\n compute_num_same_words \n");
    return;
}

void create_istogram(void) {
    printf("\n create istogram \n");
    return;
}

void save_file(void) {
    printf("\n save_file \n");
    return;
}

int get_choice(void) {
    int choice = 0;
    printf("\n Select a choice from  the below \n");
    printf("\n Select 0 to add text \n");
    printf("\n Select 1 to add new words in the dictionary \n");
    printf("\n Select 2 to enter  enter correction mode \n");
    printf("\n Select 3 to save the text \n");
    printf("\n Select 4 to see the statistics about your text \n");
    printf("\n Select 5 to exit the program\n");
    scanf("\n%d", &choice);
    return choice;
}

void insert_text(int numwords, char matrix[N][M], int  posit) {
    int i;
    int j;
    char word2[40] = { "" };

    while (strcmp(word2, "*T*E*L*O*S*")) {
        printf("\n Add the word \n");
        scanf("\n%s", word2);

        if (posit + 1 > numwords) {
            printf("\n Out of Bounds \n ");
        }

        for (i = numwords - 2; i >= posit; i--) {
            strcpy(matrix[i + 1], matrix[i]);
            if (!i)
                break;
        }
        strcpy(matrix[posit], word2);
        j++;
    }
    for (i = 0; i < j; i++) {
        printf("%s", matrix[i]);
        printf("\n j is %d\n", j);
    }
    return;
}

The problem: I have a function called insert_text. This function adds a string in the 1st position of an array (at least that is what I think it does) and it is called if choice is 0 and executes itself until the string *ΤELOS* is given. When in insert_text I print matrix I get a bunch of *(null)*s... I can count how many words matrix has (by declaring a variable j and incrementing by 1 inside the while loop, but that does not seem to work either. How can I fix this?



Solution 1:[1]

The printing code is incorrect: matrix is an array of N arrays of M characters, where you store null terminated C strings. As coded, you pass a single character just beyond the end of the array to printf for %s, which expects a string. The loop should be:

    for (j = 0; j < N; j++) {
        printf("%s ", matrix[j]);
    }

Note that char matrix[N][M]; is uninitialized, so its contents will seem random. Initialize matrix as char matrix[N][M] = { "" };

Also note that in add_new_word_dictionary(), the scanf() conversion should be scanf("%49s", word); to prevent a potential buffer overflow if the user enters a very long word.

Same in insert_text, the code should be scanf("%39s", word2) ans you should test the return value to check for input errors.

Finally, arrays are indexed from 0 in C, so insert_text should be given a position of 0 and the number of words should be N, not M.

Both the test and the insertion loop have problems too.

Here is a modified version:

// call from main as insert_text(N, matrix, 0);
//
void insert_text(int numwords, char matrix[N][M], int posit) {
    char word2[40];
    int i, j = 0;

    for (;;) {
        printf("\n Add the word \n");
        if (scanf("%39s", word2) != 1) {
            break;  // end of file or input error
        }
        if (!strcmp(word2, "TELOS")) {
            break;  // magic word
        }
        if (posit >= numwords) {
            printf("\n Out of Bounds \n");
            break;
        }
        for (i = numwords - 2; i >= posit; i--) {
            strcpy(matrix[i + 1], matrix[i]);
        }
        strcpy(matrix[posit], word2);
        j++;
    }
    for (i = 0; i < j; i++) {
        printf("%s ", matrix[i]);
    }
    printf("\n j is %d\n", j);
}

Here is a modified version of the whole program:

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

#define N 500
#define M 100

/*Version 1*/
void replace_word(char *word);
void add_new_word_dictionary(void);
void do_nothing(void);
void return_basic(void);
void check_word(void);
void compute_words(void);
void compute_characters(void);
void compute_ch_sp(void);
void compute_num_dif_words(void);
void create_istogram(void);
void save_file(void);
int get_choice(void);
void return_word(void);
void insert_text(int numwords, char matrix[N][M], int  posit);

int main() {
    int j, done = 0;
    char matrix[N][M] = { "" };

    while (!done) {
        switch (get_choice()) {
        case 0:
            insert_text(N, matrix, 0);
            break;
        case 1:
            add_new_word_dictionary();
            break;
        case 2:
            do_nothing();
            break;
        case 3:
            save_file();
            break;
        case 4:
            compute_words();
            break;
        default:
            done = 1;
            break;
        }
        for (j = 0; j < N; j++) {
            if (matrix[j][0])
                printf("%s ", matrix[j]);
        }
        printf("\n");
    }
    printf("\n End of Program \n");
    return 0;
}

void add_new_word_dictionary(void) {
    char word[50];
    printf("\nPlease enter the word\n");
    if (scanf("%49s", word) == 1)
        printf("Your word is %s\n", word);
}

void replace_word(char *word)   { printf("\n replace word \n"); }
void do_nothing(void)           { printf("\n do_nothing \n"); }
void return_basic(void)         { printf("\n return basic \n"); }
void check_word(void)           { printf("\n check word \n"); }
void compute_words(void)        { printf("\n compute_words \n"); }
void compute_characters(void)   { printf("\n compute characters \n"); }
void compute_ch_sp(void)        { printf("\n compute_ch_sp \n"); }
void compute_num_dif_words(void) { printf("\n compute_num_same_words \n"); }
void create_istogram(void)      { printf("\n create istogram \n"); }
void save_file(void)            { printf("\n save_file \n"); }

int get_choice(void) {
    int choice = -1;
    printf("\nSelect a choice from  the below \n");
    printf("Select 0 to add text \n");
    printf("Select 1 to add new words in the dictionary \n");
    printf("Select 2 to enter  enter correction mode \n");
    printf("Select 3 to save the text \n");
    printf("Select 4 to see the statistics about your text \n");
    printf("Select 5 to exit the program\n");
    scanf("%d", &choice);
    return choice;
}

// call from main as insert_text(N, matrix, 0);
//
void insert_text(int numwords, char matrix[N][M], int posit) {
    char word2[40];
    int i;

    for (;;) {
        printf("\n Add the word \n");
        if (scanf("%39s", word2) != 1) {
            break;  // end of file or input error
        }
        if (!strcmp(word2, "TELOS")) {
            break;  // magic word
        }
        if (posit >= numwords) {
            printf("\n Out of Bounds \n");
            break;
        }
        for (i = numwords - 2; i >= posit; i--) {
            strcpy(matrix[i + 1], matrix[i]);
        }
        strcpy(matrix[posit], word2);
        posit++;
    }
    for (i = 0; i < posit; i++) {
        printf("%s ", matrix[i]);
    }
    printf("\n posit is %d\n", posit);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1