1

I'm new to C, taking a university course. In one of the tasks I'm given, I deal with strings. I take strings either entered by user or parsed from a file and then use a function on them to produce an answer (if a specific quality exists).

The string can be of variable length but it is acceptable to assume that their maximum length is 80 characters.

I created the program using a

char s[81];

and then filling up the same array with the different strings each time. Since the string has to be null-terminated I just added a '\0' at index 80;

s[80] = '\0';

But then I got all kind of weird behaviors - Unrelated characters at the end of the string I entered. I assumed this is because there was space between the end of the 'real' characters and the '\0' character filled with garbage(?).

So what I did is I created a function:

void clean_string(char s[], int string_size) {
    int index = 0;
    while(index < string_size) {
        s[index++] = '\0';
    }
}

What I call clean, is just filling a string up with zero characters. I do this every time I am done dealing with a string and ready to accept a new one. Then I fill up the string again character by character and when ever I'll stop, the following character will be a '\0' for sure. To not include any magic numbers in code (81 each time I call clean_string) I used the following:

#define STRING_LENGTH 81

That works for me. The strings show no strange behavior. But I wondered if this is considered bad practice. Are there problems with this approach? Just emphasizing, I'm not asking for help in the assignment itself, but tips on how to approach these kind of situations better.

Nexaspx
  • 371
  • 4
  • 20
  • 1
    Depends on how you fill in your strings. If you use a string function like `strcpy` or `strcat`, then the string they write will already be null-terminated. – Blaze Oct 25 '18 at 12:44
  • 2
    You're just doing extra unnecessary work (80 bytes it's not too much work; imagine you had strings 16M long!). It's easy to keep track of the last valid character and add a `'\0'` when needed. – pmg Oct 25 '18 at 12:46
  • 2
    All string handling routines of the C standard library, such as `strcpy` will terminate the string with a '`\0'`, except `strncpy`, and will recognize the first null character as end-of-string. – Paul Ogilvie Oct 25 '18 at 12:46
  • 2
    Why can't you just set the terminating 0 at the point where you've put the last read character in the array and you know exactly where you ended up? If that's not possible and you want to fill the array with 0's, then I wouldn't use a function and a loop, I would just use `memset(s, 0, string_size)`. – lurker Oct 25 '18 at 12:46
  • @Blaze I am using `getchar` to read a string a character at a time until a new line is met. – Nexaspx Oct 25 '18 at 12:47
  • 2
    @Nexaspx: within your function using `getchar()` implement a running count. At the end just do `s[runningcount] = 0;` (and maybe pass `runningcount` back to the caller). – pmg Oct 25 '18 at 12:49
  • @PaulOgilvie I'm reading the string by characters. Is there still any use to `strcopy`? I never used it but from what I see it accepts a string, and I'm dealing with a stream of chars. Do I need to use some other function to read string to it? – Nexaspx Oct 25 '18 at 12:53
  • @pmg I just tried this and of course this works. Don't know why I over complicated this :) – Nexaspx Oct 25 '18 at 12:56
  • You could use `fgets`. – Paul Ogilvie Oct 25 '18 at 13:09

1 Answers1

3

Rather than prefilling the entire array with zeros, it should be simple to just add a single zero after you've read all relevant characters.

For example:

char s[STRING_LENGTH];
int c;
int idx = 0;

while (((c = getchar()) != '\n') && (idx < STRING_LENGTH - 1) && (c != EOF)) {
    s[idx++] = c;
}
s[idx] = 0;
dbush
  • 205,898
  • 23
  • 218
  • 273
  • 1
    I think it is a matter of "taste" to use s[idx]=0 or s[idx]='\0'. There is a discussion here: https://stackoverflow.com/questions/16955936/string-termination-char-c-0-vs-char-c-0 – manoliar Oct 25 '18 at 13:49
  • `(idx < STRING_LENGTH - 1)` before `((c = getchar()) != '\n')` avoids losing data. If not enough room, simply leave `stdin` unread. Yet makes little difference with OP's "assume that their maximum length is 80". – chux - Reinstate Monica Oct 25 '18 at 18:04