strchr не работает в C

Поэтому сейчас я пытаюсь написать программу на C, которая берет строку и проверяет правильную пунктуацию (например, заканчивается на ".", "?" Или "!"). Я пытаюсь использовать функцию strchr, чтобы проверить и посмотреть, является ли последний символ в строке одним из знаков препинания, используя цикл if внутри цикла for. Однако, когда я запускаю программу, кажется, что все циклы пропускаются.

Вот программа:

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

int main(void)
{
 char string[1000];
 int i,length,a,p,q,e;

 printf("Please enter a sentence with a valid punctuation.\n\n");


 for(i=0;i<1000;i++)
 {
  fgets(string,2,stdin);
  p=strchr(string,'.');
  q=strchr(string,'?');
  e=strchr(string,'!');
  if(string[sizeof(string)-1]=='.'||'?'||'!')
  {
   printf("\nYay a sentence!");
   break;
  }
  else if((p && q && e)==NULL)
  { 
   printf("You didn't provide any punctuation. Goodbye.");
   exit(a);
  }
 }
 printf("You entered the sentence:\n %s",string);

 return 0;
}

Я пробовал это так много разных способов, таких как взамен strstr или даже сохранял его другим способом через get (который я быстро выучил через gcc, и некоторые исследования не подходят).

Я просто совершенно заблудился, почему это не работает, когда я ввожу предложение без знаков препинания.

Извините, если это действительно просто, я новичок в этом.

Заранее спасибо.

2 ответа

Решение

Вы неправильно поняли возвращаемое значение strchr: он не возвращает индекс символа; вместо этого он возвращает указатель на символ, который вы ищете.

char *p=strchr(string, '.');
char *q=strchr(string, '?');
char *e=strchr(string, '!');

К тому же, sizeof не возвращает фактическую длину строки; он возвращает 1000, что является размером string массив. Вам нужно использовать strlen вместо.

В заключение, string[strlen(string)-1]=='.'||'?'||'!' не сравнивает последний символ с одним из трех символов. Всегда возвращается 1, потому что коды символов ? а также ! не ноль, и поэтому логическое ИЛИ || оператор рассматривает их как true значение.

То же самое касается (p && q && e)==NULL) условие: оно не проверяет, что все три значения NULL; один из них NULL было бы достаточно, чтобы произвести равенство, но это не то, что вы хотите.

Вот как это исправить:

char last = string[strlen(string)-1];
// Skip '\n's at the end
while (last != 0 && (string[last] == '\n' || string[last] == '\r')) {
    last--;
}
if (last == '.' || last == '?' || last == '!') {
    ...
}
// Using implicit comparison to NULL is idiomatic in C
if (!p && !q && !e) {
    ...
}
  • strchr возвращает указатель
  • выражения как hoge==a||b||c странные Вы должны написать их отдельно.

фиксированный код:

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

int main(void)
{
 char string[1000];
 int i,length,a;
 char *p,*q,*e;

 printf("Please enter a sentence with a valid punctuation.\n\n");


 for(i=0;i<1000;i++)
 {
  fgets(string,2,stdin);
  p=strchr(string,'.');
  q=strchr(string,'?');
  e=strchr(string,'!');
  if(string[sizeof(string)-1]=='.'||string[sizeof(string)-1]=='?'||string[sizeof(string)-1]=='!')
  {
   printf("\nYay a sentence!");
   break;
  }
  else if(p==NULL&&q==NULL&&e==NULL)
  { 
   printf("You didn't provide any punctuation. Goodbye.");
   exit(a);
  }
 }
 printf("You entered the sentence:\n %s",string);

 return 0;
}

Замечания:

  • string[sizeof(string)-1] будет неопределенным, потому что это означает, string[999] и это никогда не будет написано, потому что вы говорите fgets тот string имеет только 2 элемента.
  • a используется в качестве аргумента exit является неопределенным. Пожалуйста, инициализируйте это.
  • length не используется.
Другие вопросы по тегам