Моя программа, которая создает сокращение массива char, ничего не печатает.Где моя ошибка? - PullRequest
0 голосов
/ 20 апреля 2019

Я должен создать программу, которая создает массив с сокращением константного массива char. Хотя моя программа не возвращает никаких ошибок, она также не печатает какие-либо символы в определенных местах печати. Поэтому я предполагаю, что моя программа не работает должным образом и не заполняет мой массив какими-либо символами.

void abbrev(const char s[], char a[], size_t size) {
    int i = 0;
    while (*s != '\0') {
        printf('%c', *s);
        if (*s != ' ' && *s - 1 == ' ') {
            a[i] = *s;
            i++;
            printf('%c', a[i]);
        }
        s++;
    }
}


void main() {
    char jordan1[60] = "  Electronic      Frontier  Foundation ";
    char a[5];
    size_t size = 5;
    abbrev(jordan1, a, size);
    system("PAUSE");
}

Фактический результат - ничто. По крайней мере, я так полагаю, поскольку моя консоль ничего не показывает. Результат должен быть "EFF", а размер size_t должен ограничивать мой массив символов a, если сокращение слишком длинное. Поэтому он должен реализовывать буквы только до тех пор, пока мой массив не заполнится, а затем '\ 0', но я еще не реализовал его, поскольку моя программа явно не заполняет массив вообще.

Ответы [ 3 ]

0 голосов
/ 20 апреля 2019
#include <stdio.h>
#include <ctype.h>

/* in: the string to abbreviate
   out: output abbreviation. Function assumes there's enough room */
void abbrev(const char in[], char out[])
{
    const char *p; 
    int zbPosOut = 0;     /* current zero-based position within the `out` array */

    for (p = in; *p; ++p) { /* iterate through `in` until we see a zero terminator */

        /* if the letter is uppercase
              OR if (the letter is alphabetic AND we are not at the zero 
              position AND the previous char. is a space character) OR if the
              letter is lowercase and it is the first char. of the array... */
        if (isupper(*p) || (isalpha(*p) && (p - in) > 0 && isspace(p[-1])) 
                        || (islower(*p) && p == in)) {

            out[zbPosOut++] = *p; /* ... then the letter is the start letter
                          of a word, so add it to our `out` array, and 
                          increment the current `zbPosOut` */
        }
    }
    out[zbPosOut] = 0; /* null-terminate the out array */
}

Этот код говорит о многом в нескольких строках.Давайте посмотрим:

isupper(*p) || (isalpha(*p) && (p - in) > 0 && isspace(p[-1])) 
           || (islower(*p) && p == in)

Если текущий символ (*p) является заглавным символом ИЛИ, если это алфавит (isalpha(*p), а предыдущий символ p[-1] является пробелом, то мы можемсчитать *p первым символом слова, и его следует добавить в наш массив out. Мы включаем тест (p - in) > 0, потому что если p == in, то мы находимся в нулевой позиции массива и, следовательно,p[-1] не определено.

Порядок в этом выражении имеет большое значение. Если бы мы поставили (p - in) > 0 после теста isspace(p[-1]), то мы бы не воспользовались преимуществомлень оператора &&: как только он встречает ложный операнд, следующий операнд не вычисляется. Это важно, потому что если p - in == 0, то мы не хотим вычислять выражение isspace(p[-1]).мы написали тесты, чтобы убедиться, что isspace(p[-1]) вычисляется после того, как мы не на нулевой позиции.

Финальное выражение (islower(*p) && p == in) обрабатывает случай, когда первая буква строчная.ase.

out[zbPosOut++] = *p;

Мы добавляем символ *p в массив out.Текущее положение out отслеживается переменной zbPosOut, которая впоследствии увеличивается (поэтому мы используем postscript ++ вместо префикса).

Код для проверки работы abbrev:

int main()
{
    char jordan1[] = "  electronic      frontier  foundation ";
    char out[16];

    abbrev(jordan1, out);
    puts(out);

    return 0;
}

В качестве выхода выдается eff.Чтобы это выглядело как аббревиатура, мы можем изменить код, добавив к буквам от *p до out:

out[zbPosOut++] = toupper(*p);

, которые пишут с заглавной буквы каждую букву, добавленную в массив out (если *p уже в верхнем регистре, toupper просто возвращает *p).

0 голосов
/ 20 апреля 2019
void print_without_duplicate_leading_trailing_spaces(const char *str)
{
    while(*str == ' ' && *str) str++;
    while(*str)
    {
        if(*str != ' ' || (*str == ' ' && *(str + 1) != ' '  && *str))
        {
            putchar(*str);
        }
        str++;
    }
}
0 голосов
/ 20 апреля 2019

То, что вы хотите сделать, можно упростить с помощью цикла for().

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

void abbrev(const char s[], char a[], size_t size) {
  int pos = 0;
  // Loop for every character in 's'.
  for (int i = 0; i < strlen(s); i++)
    // If the character just before was a space, and this character is not a
    // space, and we are still in the size bounds (we subtract 1 for the
    // terminator), then copy and append.
    if (s[i] != ' ' && s[i - 1] == ' ' && pos < size - 1)
      a[pos++] = s[i];
  printf("%s\n", a); // Print.
}

void main() {
  char jordan1[] = " Electronic    Frontier  Foundation ";
  char a[5];
  size_t size = 5;
  abbrev(jordan1, a, size);
}

Однако я не думаю, что это лучший способ достичь того, что вы пытаетесь сделать. Во-первых, char s[0] не может быть получено из-за проверки предыдущего символа. Это подводит меня ко второй причине: по первому индексу вы будете проверять s[-1], что, вероятно, не очень хорошая идея. Если бы я реализовывал эту функцию, я бы сделал это:

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

void abbrev(const char s[], char a[], size_t size) {
  char *str = strdup(s); // Make local copy.
  size_t i = 0;
  // Break it up into words, then grab the first character of each word.
  for (char *w = strdup(strtok(str, " ")); w != NULL; w = strtok(NULL, " "))
    if (i < size - 1)
      a[i++] = w[0];
  free(str); // Release our local copy.
  printf("%s\n", a);
}

int main() {
  char jordan1[] = "Electronic    Frontier  Foundation ";
  char a[5];
  size_t size = 5;
  abbrev(jordan1, a, size);
  return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...