У меня есть следующий код, который я использую для нормализации массива символов. В конце процесса нормализованный файл имеет часть старого вывода, оставшегося в конце. Это нужно для того, чтобы i достиг конца массива перед j. В этом есть смысл, но как мне удалить лишние символы? Я исхожу из java, поэтому прошу прощения, если делаю ошибки, которые кажутся простыми. У меня такой код:

/* The normalize procedure normalizes a character array of size len 
   according to the following rules:
     1) turn all upper case letters into lower case ones
     2) turn any white-space character into a space character and, 
        shrink any n>1 consecutive whitespace characters to exactly 1 whitespace

     When the procedure returns, the character array buf contains the newly 
     normalized string and the return value is the new length of the normalized string.

     hint: you may want to use C library function isupper, isspace, tolower
     do "man isupper"
*/
int
normalize(unsigned char *buf,   /* The character array contains the string to be normalized*/
                    int len     /* the size of the original character array */)
{
    /* use a for loop to cycle through each character and the built in c funstions to analyze it */
    int i = 0;
    int j = 0;
    int k = len;

    if(isspace(buf[0])){
        i++;
        k--;
    }
    if(isspace(buf[len-1])){
        i++;
        k--;
    }
    for(i;i < len;i++){
        if(islower(buf[i])) {
            buf[j]=buf[i];
            j++;
        }
        if(isupper(buf[i])) {
            buf[j]=tolower(buf[i]);
            j++;
        }
        if(isspace(buf[i]) && !isspace(buf[j-1])) {
            buf[j]=' ';
            j++;
        }
        if(isspace(buf[i]) && isspace(buf[i+1])){
            i++;
            k--;
        }
    }

   return k;

}

Вот пример вывода:

halb mwqcnfuokuqhuhy ja mdqu nzskzkdkywqsfbs zwb lyvli HALB MwQcnfuOKuQhuhy Ja mDQU nZSkZkDkYWqsfBS ZWb lyVLi

Как видите, конец повторяется. В результате присутствуют как новые нормализованные данные, так и старые оставшиеся ненормализованные данные. Как я могу это исправить?

1
Lesha 19 Фев 2014 в 03:16
Увидев (а) образец ввода , (b) соответствующий образец вывода , (c) правильный образец вывода и (d) все примерно с 1/10 представленных здесь данных, которые по-прежнему вызывают ту же проблему , было бы весьма желательно. Также было бы намного легче отлаживать вам , если бы в вашем распоряжении было все вышеперечисленное.
 – 
WhozCraig
19 Фев 2014 в 03:31
Я отредактировал вывод, чтобы он был короче, чтобы было легче увидеть проблему. После нормализованной части ненормализованная часть повторяется.
 – 
Lesha
19 Фев 2014 в 03:38
Спасибо. Просто из любопытства, когда было выдано это задание, изучали ли вы указатели и их многочисленные варианты использования, потому что может быть в некотором роде упражнением в обходе двух из них в вашем буфере. Просто любопытно.
 – 
WhozCraig
19 Фев 2014 в 03:44
Мы изучили указатели за несколько недель до того, как было выдано это задание. Хотя использование указателей является частью присваивания, которое не является целью присваивания.
 – 
Lesha
19 Фев 2014 в 03:47
1
Что касается вашей проблемы, это может быть так же просто, как сами параметры назначения. В нем ничего не говорится о завершении строки (т.е. установке терминатора nulchar); он просто говорит, что верните окончательную длину, когда закончите. Фактически, нет никаких гарантий, что input завершен; почему вывод должен быть таким? Проще говоря, ваш код уже может быть правильным, и вы просто неправильно отображаете результаты. Имхо явно не хватает этой части задания.
 – 
WhozCraig
19 Фев 2014 в 03:59

3 ответа

Лучший ответ

Добавить нулевой терминатор

k[newLength]='\0';
return k;
2
Grady Player 19 Фев 2014 в 03:35
Я полагаю, вы имели в виду buf[j+1] = '\0'. Это похоже на достижение цели, но добавляет дополнительный символ в конец массива (при распечатке в конце появляется X). Я неправильно добавил указатель?
 – 
Lesha
19 Фев 2014 в 03:49
Примечание: если переданный буфер является не завершенной строкой и последний символ в буфере не является суффиксом с двумя пробелами, это может вызвать UB.
 – 
WhozCraig
19 Фев 2014 в 04:29
Это означает, что если упакованный буфер без пробелов и заканчивающийся чем-либо, кроме двух пробельных символов (следовательно, последний будет обрезан), заставит вас записать в buf[len] в качестве терминатора. Адресный регион: buf[0...(len-1)]. То, что длина была передана этой функции, не случайно. В назначении ничего не говорится о прекращении деятельности. Я искренне думаю, что проблема была в коде создания отчетов , а не в алгоритме (хотя, по общему признанию, я не рассматривал алгоритм внимательно). См. Мою ссылку в общем комментарии, чтобы понять, что я имею в виду.
 – 
WhozCraig
19 Фев 2014 в 08:07
Я сбит с толку ... Я не знаком ни с одним доменом, требующим 2 символа пробела, кроме некоторых форматов. заголовки http и т. д. в чем опасность копирования строки "dog" в буфер char [4]
 – 
Grady Player
19 Фев 2014 в 08:17
По-видимому, я не правильно говорю. Нет ничего плохого в том, чтобы скопировать строку dog в буфер символов длиной 4. Существует существенная проблема завершение строки dog в символьный буфер длиной 3 . Что эта функция может быть задана. char buf[3] = { 'd', 'o', 'g' }; normalize(buf,3); в присвоении ничего не говорится о завершении строки, и все, что вы знаете о буфере, это то, что вам нужно обработать символы len и вернуть количество символов после нормализация (которая все еще может быть len). Честно говоря, не могу сказать яснее, чем это.
 – 
WhozCraig
19 Фев 2014 в 09:10

Исправить вот так

int normalize(unsigned char *buf, int len) {
    int i, j;

    for(j=i=0 ;i < len; ++i){
        if(isupper(buf[i])) {
            buf[j++]=tolower(buf[i]);
            continue ;
        }
        if(isspace(buf[i])){
            if(!j || j && buf[j-1] != ' ')
                buf[j++]=' ';
            continue ;
        }
        buf[j++] = buf[i];
    }
    buf[j] = '\0';

    return j;
}
0
BLUEPIXY 19 Фев 2014 в 04:24

Или? добавить нулевой терминатор

    k[newLength] = NULL;
    return k;
0
username 19 Фев 2014 в 04:44