简体   繁体   中英

Random Characters Appearing When Printing Arrays

I'm relatively new to coding array functions in C. After numerous tries, I've decided to surrender and ask for help.

I wish to the user to input the words and store them into the 2d array words. The problem is that it prints the words but also prints out random characters.

#include "mp1_lib.h"

void get_words(int n, char words[][16])
{       
    char c = ' ';
    char check;

    for(int x=0; x <= n; x++)
        {
            for(int y=0; y < 16; y++)
            {                   
                c = getchar();
                check = c;

                if (check == '\n')
                    {    
                        break;    
                    } 

                words[x][y] = c;                        
            }    
        }           
}             

void print_words(int n, char words[][16]) 
{
    for(int x=1; x <= n; x++)
    {   
        for(int y=0; y < 16; y++)
        {   
                if (words[x][y] == '\n')
                {
                    break;
                } 

                putchar(words[x][y]);

        }

        printf("\n");
    }    
}

Not too familiar with c. But it appears like you are not addding the new line character to the words array in get_words .

check = c;

if (check == '\n')
{

    break;

} 

words[x][y] = c;

So when printing in print_words this will never be true.

if (words[x][y] == '\n')
{
    break;
} 

That means that whatever happens to be in the memory location is what will get printed.

In C, a string is an array of characters with the nul-terminating character '\\0' as the character that marks the end of the contents of the string within the array. That is how all string functions like strlen or printf using the '%s' format specifier to print a string -- know where the string stops.

If you do not nul-terminate the array of characters -- then it is not a string, it is simply an array and you cannot pass an un-terminate array to any function expecting a string - or it won't know where the string ends (and in the case of printf will just print whatever unspecified character happens to be in memory until it comes upon a '\\0' to stop the output (or SegFaults).

If you don't nul-terminate the words in your array, then you will have to have some way to store the number of characters in each word, so your print function will know where to stop printing. (if you have a two-letter word like "Hi" in a 16-char array, you can only print 2 characters from the array. Especially if it is an uninitialized array, then you will simply get gibberish printed for characters 3-16 .

Your second problem is -- "How do you know how many words you have stored in your array?" -- you don't return a value from getwords , so unless you change the function type to int and return the number of words that you stored in your array, your only other option is to pass a pointer to an integer and update the value at that address so the value is available back in the calling function. Either way is fine, you generally only worry about making a value available through a pointer if you are already returning another value and need a second method to make another updated value visible back in the calling function ( main() here).

Putting those pieces together, and passing a pointer to the number of words to getwords to make the number of words entered available back in main() (so you know how many words print_words has to print), you could do something similar to the following:

#include <stdio.h>
#include <ctype.h>

#define MAXC 16     /* if you need constants, define them */
#define MAXW 32

void getwords (char (*words)[MAXC], int *n)
{
    int col = 0;                        /* column count */
    while (*n < MAXW) {                 /* while words < MAXW */
        int c = getchar();              /* read char */
        /* column reaches MAXC-1 or if whitespace or EOF */
        if (col == MAXC - 1 || isspace(c) || c == EOF) {
            if (col) {                  /* if col > 0 */
                words[(*n)++][col] = 0; /* nul-terminate, increment n */
                col = 0;                /* set col to zero */
            }
            if (c == EOF)               /* if char EOF - all done */
                return;
        }
        else    /* otherwise - just add char to word */
            words[*n][col++] = c;
    }
}

void prnwords (char (*words)[MAXC], int n)
{
    for (int i = 0; i < n; i++) /* loop over each of n-words & print */
        printf ("words[%2d]: %s\n", i, words[i]);
}

int main (void) {

    char words[MAXW][MAXC] = {""};  /* intiliaze words all zero */
    int nwords = 0;                 /* number of words zero */

    getwords (words, &nwords);
    prnwords (words, nwords);

    return 0;
}

( note: when reading characters into the words array, you must check the number of character read again the maximum characters per-word ( MAXC ) and the number of words against the maximum number of words/rows in your array ( MAXW ) to prevent writing outside of your array bounds -- which will invoke Undefined Behavior in your program)

( note: the ctype.h header was included to simplify checking whether the character read was whitespace (eg a space , tab , or newline ). If you can't use it, then simply use an if (c == ' ' || c == '\\t' || c == '\\n') instead.)

Example Use/Output

$ echo "my dog has fleas and my cat has none" | ./bin/getwords
words[ 0]: my
words[ 1]: dog
words[ 2]: has
words[ 3]: fleas
words[ 4]: and
words[ 5]: my
words[ 6]: cat
words[ 7]: has
words[ 8]: none

Your words have neither the newline character (which makes your code print garbage) nor the terminating NULLs (which makes them illegal as C strings). At least add words[x][y]="\\n" before breaking the inner loop. Or, rather, move the if check after the assignment words[x][y]=c; . And yes, the loop should go from 0 to n-1 .

As a side note, you do not need the variable check : just use c .

I tried to assign space as a placeholder for the 15 characters and it worked. Thanks, everyone! :)

#include "mp1_lib.h"


void get_words(int n, char words[][16])
{

    char c = ' ';
    char check;


    for(int x=0; x < n; x++)
        {
            for(int y=0; y < 16; y++)
            {   
                words[x][y] = ' ';

            }

        }


    for(int x=0; x < n; x++)
        {
            for(int y=0; y < 16; y++)
            {   

                c = getchar();
                check = c;

                if (check == '\n')
                    {
                        break;
                    } 
                words[x][y] = c;
            }

        }


} 




void print_words(int n, char words[][16]) 
{

    for(int x=0; x < n; x++)
    {   
        for(int y=0; y < 16; y++)
        {   

                putchar(words[x][y]);

        }

        printf("\n");
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM