Функция Array удаляет первый символ из массива - PullRequest
0 голосов
/ 27 февраля 2012

Я пытаюсь написать функцию для большого проекта, который состоит из работы с массивами символов.Текущая функция, над которой я работаю, должна сохранять только алфавитные символы и удалять любые специальные символы (например,! # @ $?) И пробелы.Моя текущая функция работает, но по какой-то причине, когда я ее запускаю, первый символ массива всегда удаляется.Почему так и как я могу сделать так, чтобы вместо этого был сохранен первый символ?

#include <stdio.h>

int main(void)
{
  char phrase[101];

  printf("Enter a phrase to change:");
  fgets(phrase, 101, stdin);

  printf("original phrase: %s", phrase);

  int i = 0, j = 0;
  while(phrase[i] != '\0')
  {
    if( ('A' <= phrase[i] && phrase[i] >= 'Z') || 
        ('a' <= phrase[i] && phrase[i] >= 'z') )
    {
       phrase[j] = phrase[i];
       i++;
       j++;
    }
    else
      i++;

    phrase[j] = '\0';
  }

  printf("new phrase: %s\n", phrase);

  return 0;
}

Ответы [ 4 ]

4 голосов
/ 27 февраля 2012

Направление ваших операторов сравнения неверно. Вместо:

if( ('A' <= phrase[i] && phrase[i] >= 'Z') || 
    ('a' <= phrase[i] && phrase[i] >= 'z') )

Вам нужно:

if( ('A' <= phrase[i] && phrase[i] <= 'Z') || 
    ('a' <= phrase[i] && phrase[i] <= 'z') )

То, как вы написали, пропустит заглавные буквы, поэтому, возможно, именно поэтому пропущен первый символ вашего ввода.

Вам также следует переместить строку phrase[j] = '\0'; после цикла, поскольку в противном случае вы можете перезаписать следующий символ для чтения.

2 голосов
/ 27 февраля 2012

Ну, я предполагаю, что первый символ не алфавитно-цифровой. У вас есть строка, специально удаляющая его:

phrase[j] = '\0';

Либо вы удаляете первый символ (если он не буквенно-цифровой), либо вы удаляете второй (если первый является буквенно-цифровым).

Вы должны ставить завершающий \ 0 только после того, как закончите сканирование строки.

РЕДАКТИРОВАТЬ: Как указал @interjay, ваша проверка неверна, поэтому ваш первый символ всегда рассматривается как не буквенно-цифровой. Вот почему вы стираете его.

1 голос
/ 27 февраля 2012

Полагаю, потому что ваш первый символ - единственный заглавный, а ваша логика неверна.

if( ('A' <= phrase[i] && phrase[i] >= 'Z') ||    
     ('a' <= phrase[i] && phrase[i] >= 'z') )     

должно быть

if( ('A' <= phrase[i] && phrase[i] <= 'Z') ||    
     ('a' <= phrase[i] && phrase[i] <= 'z') )     

хотя библиотека C предоставляет isalpha, которая также будет работать с наборами символов EBCDIC, где от 'A' до 'Z' не являются последовательными.

0 голосов
/ 27 февраля 2012

Как насчет использования isalpha() из ctype.h?

if (isalpha(phrase[i])) {
    phrase[j] = phrase[i];
    /* ... */
}

Но если говорить о вашем вопросе:

Цикл while посещается только один раз, поскольку предикатцикл не выполняется после первого запуска, потому что вы устанавливаете phrase[j] на '\0' при первом запуске цикла.

Редактировать: О, я не читал ifсостояние тщательно.Как указывает @interjay, это также неправильно.

...