Я новичок в C, учусь в университете. В одном из заданий я имею дело со струнами. Я беру строки, введенные пользователем или извлеченные из файла, а затем использую для них функцию для получения ответа (если существует определенное качество).
Строка может быть переменной длины, но допустимо предположить, что ее максимальная длина составляет 80 символов.
Я создал программу, используя
char s[81];
а затем каждый раз заполнять один и тот же массив разными строками. Поскольку строка должна оканчиваться нулем, я просто добавил '\ 0' в индекс 80;
s[80] = '\0';
Но потом у меня появилось много странного поведения - несвязанные символы в конце введенной мной строки. Я предположил, что это связано с тем, что между концом «настоящих» символов и символом «\ 0» был пробел, заполненный мусором (?).
Итак, я создал функцию:
void clean_string(char s[], int string_size) {
int index = 0;
while(index < string_size) {
s[index++] = '\0';
}
}
То, что я называю чистым, - это просто заполнение строки нулями. Я делаю это каждый раз, когда заканчиваю работать со строкой и готов принять новую. Затем я снова заполняю строку символом за символом, и когда я когда-нибудь остановлюсь, следующий символ обязательно будет '\ 0'. Чтобы не включать в код магические числа (81 каждый раз, когда я вызываю clean_string), я использовал следующее:
#define STRING_LENGTH 81
Это подходит для меня. Струны не показывают странного поведения. Но мне было интересно, считается ли это плохой практикой. Есть ли проблемы с таким подходом? Подчеркиваю, я прошу не о помощи в самом задании, а о том, как лучше подходить к подобным ситуациям.
Вы просто делаете лишнюю ненужную работу (80 байт - это не так уж много; представьте, что у вас есть строки длиной 16 Мбайт!). Легко отслеживать последний действительный символ и при необходимости добавлять '\0'.
Все подпрограммы обработки строк стандартной библиотеки C, такие как strcpy, завершают строку символом '\0', кроме strncpy, и распознают первый нулевой символ как конец строки.
Почему вы не можете просто установить завершающий 0 в точке, где вы поместили последний прочитанный символ в массив, и вы точно знаете, где вы оказались? Если это невозможно и вы хотите заполнить массив нулями, я бы не стал использовать функцию и цикл, я бы просто использовал memset(s, 0, string_size).
@Blaze Я использую getchar для чтения строки по символу за раз, пока не встретится новая строка.
@Nexaspx: в вашей функции с помощью getchar() реализуйте текущий счетчик. В конце просто выполните s[runningcount] = 0; (и, возможно, верните runningcount вызывающему абоненту).
@PaulOgilvie Я читаю строку по символам. Есть ли еще толк от strcopy? Я никогда не использовал его, но из того, что я вижу, он принимает строку, а я имею дело с потоком символов. Нужно ли мне использовать какую-то другую функцию для чтения строки?
@pmg Я только что попробовал, и, конечно, это работает. Не знаю, зачем я это усложнял :)
Вы можете использовать fgets.





Вместо того, чтобы предварительно заполнять весь массив нулями, должно быть просто добавить один ноль после того, как вы прочитали все соответствующие символы.
Например:
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;
Я думаю, что использовать s [idx] = 0 или s [idx] = '\ 0' - дело вкуса. Здесь есть обсуждение: stackoverflow.com/questions/16955936/…
(idx < STRING_LENGTH - 1) до ((c = getchar()) != '\n') позволяет избежать потери данных. Если места недостаточно, просто оставьте stdin непрочитанным. Тем не менее, не имеет большого значения с OP, «предположим, что их максимальная длина составляет 80».
Зависит от того, как вы набираете свои струны. Если вы используете строковую функцию, такую как
strcpyилиstrcat, то записываемая ими строка уже будет завершена нулем.