0

I am checking if a function returns true, it prints out valid strings according some other function I got. At the moment, it's printing it out correctly but it is also printing empty lines which seem to correspond to the invalid strings.

How can I make these empty lines go away?

Here is my code:

int main()
{
    int i, count = 0;
    char input[10];
    char validStr[10][60] = {""};
    for (i = 0; i < 60; ++i){
        if(fgets(input,10, stdin) == NULL){
            break;
        }
        input[strcspn(input,"\n")] = '\0';
        if(checkIfValid(input)){
            memcpy(validStr[i],input,sizeof(input));
            count++;
        }
    }
    printf("%d\n",count);
    for (int j = 0 ; j < count; ++j){
        printf("%s\n",validStr[j]); 
    }
}

The count indicates it is printing only the valid strings but as you can tell by the pic it prints white lines.

enter image description here

Note: For various reasons the program needs to follow the current order so the output is printed after the first for loop.

Thanks in advance!

3
  • 10 chars is too short by 1 for a 10-character string (no room for '\0'). Don't skimp on input buffer size. char input[1024]; is fine (reduce accordingly on embedded devices) Note how you allows 60 chars for each string in char validStr[10][60] = {""}; Instead of memcpy(validStr[i],input,sizeof(input)); use strcpy (validStr[i],input); Commented Nov 18, 2021 at 7:12
  • I am allowing 10 characters and 60 strings, not the other way around. Commented Nov 18, 2021 at 7:17
  • Oops sorry, you had [10][60] to begin with -- just swap the bounds around :) Commented Nov 18, 2021 at 7:25

2 Answers 2

1

Instead of this:

    if(checkIfValid(input)){
        memcpy(validStr[i],input,sizeof(input));
        count++;
    }

This:

    if(checkIfValid(input)){
        memcpy(validStr[count],input,sizeof(input));
        count++;
    }

As others have pointed out in the comments, you want to safely secure that string copy. May I suggest:

    if(checkIfValid(input)){
        char* dst = validStr[count];
        size_t MAXLEN = 10;
        strncpy(dst, input, MAXLEN);
        dest[MAXLEN-1] = '\0';
        count++;
    }
Sign up to request clarification or add additional context in comments.

1 Comment

and voila! thanks!
0

Continuing from the comment, if you want to store the entire string, you need to provide adequate space for the nul-terminating character.

AAAAAAAAAA
QELETIURTE
...

contain strings that are 10 characters long and will not fit in input as declared char[10].

Instead of looping with a for, allow the return from fgets() control your read-loop and keep count as a condition controlling the loop to ensure you protect your array bounds, e.g.

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

#define MAXC 128    /* if you need a constant, #define one (or more) */
#define NSTR  10

int checkIfValid (const char *s) { return 1; (void)s; }

int main(void)
{
    size_t count = 0;
    char input[MAXC];
    char validStr[NSTR][MAXC] = {""};
    
    while (count < NSTR && fgets (input, sizeof input, stdin)) {
        input[strcspn(input,"\n")] = '\0';
        if(checkIfValid(input)){
            strcpy (validStr[count], input);
            count++;
        }
    }
    
    printf ("%zu\n",count);
    for (size_t j = 0 ; j < count; ++j) {
        printf("%s\n",validStr[j]); 
    }
}

(adjust your array declaration for 60 strings of 10 characters each)

If you want to cut off at 9 characters and ensure the stings are nul-terminated, @selbie has that covered.

Example Use/Output

With your data (as good as I could read it) in dat/validstr.txt you could do:

$ ./bin/validstring <dat/validstr.txt
6
AAAAAAAAAA
QELETIURTE
321qweve
sdsdsdfFF
GRSGGFDDSS
toLotssAAA

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.