繁体   English   中英

C 语言在输入的词中查找T或t

[英]C language finding T or t in the entered word

您有兴趣查找在单词的前半部分包含字母“t”或“T”的单词(如果有的话,包括中间字母)。 具体来说,如果单词的前半部分确实包含“t”或“T”,则您的程序应该 output a 1。如果前半部分不包含字母“t”或“T”,但后半部分包含,那么你的程序应该是 output a 2。否则,如果单词中根本没有 't' 或 'T',你的程序的 output 应该是 -1。 您可以假设输入的单词不超过 50 个字母。

 #include <stdio.h>
int main (void){
    int i=0;
    char word[51];
    int l=0;
    int half;
    char found1='T';
    char found2='t';
    
    
    scanf("%s",word);
    while (word[i]!='\0'){
        i++;
        
    }
    half=i/2;
    while(word[l]!='\0'){
         scanf("%s",word);
         l++;
        if((word[l]!=half)&&((word[l]==found1)&&(word[l]==found2))){
            printf("1");
        }
    if((word[l]!=i)&&((word[l]==found1)&&(word[l]==found2))&&(word[l]>=half)){
        printf("2");
    }
    }
    if(i%2!=0){
        printf("1");
    }else{
        printf("-1");
    }
    return 0;
}

尽可能简单地分解它:


在字符串中查找Tt的索引。

你找到了吗?

  • 不,output 0然后退出

上半年找到了吗?

  • 不,output 2然后退出

Output 1并退出。


获取输入:

char word[52];
fgets(word, sizeof(word), stdin);

使用以下命令确定字符串的长度:

int n = strlen(word) - 1;  // Don’t count the '\n' at the end of the input

请记住 integer 除法向零舍入,因此:

int half = (n + 1) / 2;

任何< half都在上半场。 任何 half都在下半场。

考虑一个没有#include 的 C 程序可能是有益的。

int main(int argc, char *argv[])
/*
* Assume the input word is argv[1], empty word (not containing T) if
* no argument.  The result is in the return value of the main
* function, so we don't need to include stdio to print it.
*/
{
    if (argc < 2)
        return -1; // no T

    char *word = argv[1];

    int found = -1, length = 0, ch;
    while ((ch = *(unsigned char*)word++) != 0)
    {
        ++length;
        if (found < 0 && (ch == 't' || ch == 'T'))
            found = length;
    }

    if (found < 0)
        return -1; // no T

    return 2*(found -1) < length? 1: 2;
}

测试时, -1显示为255

$ gcc -W -Wall -g so.c
$ ./a.out t; echo $?
1
$ ./a.out o; echo $?
255
$ ./a.out to; echo $?
1
$ ./a.out oto; echo $?
1
$ ./a.out ot; echo $?
2

但是,非 ASCII 字符无法按预期工作。 下面,参数的第一个字符是hwair ,在 UTF-8 编码中占四个字节:

$ ./a.out 𐍈tooo; echo $?
2

检测两件事就足够了:

  • 单词的长度。

  • 第一个tT的偏移量。

“单词”不需要存储,只需检测其结尾即可。
无需小 (50) 个字母限制。

  #include <ctype.h>
  #include <stdio.h>

  int main() {
    unsigned long long word_length = 0;
    unsigned long long t_offset = 0;  // First letter in a word is at offset 1.
    int ch;
    
    do {
      ch = getchar();
      if (isalpha(ch)) {
        word_length++;
        if ((ch == 't' || ch == 'T') && (t_offset == 0)) {
          // Record offset of first "Tee".
          t_offset = word_length;
        }
      } else {
        // Detect end-of-word
        if (word_length > 0) {  
          const char *output = "-1";
          if (t_offset > 0) {
            if (t_offset <= (word_length+1)/2) output = "1";
            else output = "2"; 
          }
          puts(output);
          word_length = 0;
          t_offset = 0;
        }
      }
    } while (ch != EOF);
  }

虽然您可以逐个字符地进行比较,但 C 提供了char *strpbrk(const char *s, const char *accept) ,它将在s中提供第一个字节(字符)的 position accept 使用"Tt"作为您的acceptword作为s您会收到指向word中第一次出现'T''t'的指针,例如

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

#define MAXWORD 51

int main (void) {
  
  char word[MAXWORD], *ptr2t = NULL;  /* storage and ptr to t or T */
  size_t len = 0, pos = 0, mid = 0;   /* word len, tT pos & mid pos */
  
  fputs ("\nenter word (50 char max): ", stdout);   /* prompt */
  
  if (!fgets (word, MAXWORD, stdin)) {      /* read up  to 50 chars */
    puts ("(user canceled input)");
    return 0;
  }
  word[(len = strcspn (word, "\n"))] = 0;   /* save len, trim \n from end */
  
  if (!(ptr2t = strpbrk (word, "Tt"))) {    /* locate 't' or 'T' in word */
    puts ("-1");
    return 0;
  }
  
  if (len == 1) {   /* if length 1, no determination of half is possible */
    puts ("(length is 1, half determination not possible)");
    return 0;
  }
  
  mid = len / 2;                  /* get mid position */
  pos = ptr2t - word;             /* get postion in word */
  
#ifdef ODD_MID_IN_1ST             /* if considering mid character in odd */
  if (len & 1) {                  /* length part of 1st half, add 1 to  */
    mid += 1;                     /* mid.                               */
  }
#endif

  puts (pos < mid ? "1" : "2");   /* output 1 in 1st half, 2 otherwise. */
}

根据我的评论,您还必须处理输入长度为1的情况,因为不能确定一半(根据需要处理),并且您必须确定奇数长度单词中中间字符的哪一半属于。默认情况下,中间字符属于下半部分。 定义ODD_MID_IN_1ST将更改行为以将中间字符放在上半部分(由您决定)。

编译

使用gcc ,您可以使用:

gcc -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast -o bin/tin1sthalf tin1sthalf.c

其中选项-Wall -Wextra -pedantic -Wshadow启用完整警告(大部分)并检查是否有阴影变量。 -std=c11指定语言标准为 C11, -Ofast是针对 gcc >= 4.6 的完全优化,在此之前优化级别仅限于O0O1O2O3 添加-Werror以将警告视为错误(推荐)。 可执行文件 output -o将放置在bin/目录中(根据需要更改)。

始终在启用完全警告的情况下进行编译(每个编译器都提供启用警告的选项)并且在没有警告的情况下编译之前不要接受代码( -Werror防止你作弊......)

示例使用/输出

显示程序的各种特殊情况处理和一般 output:

$ ./bin/tin1sthalf

enter word (50 char max): t
(lenght is 1, half determination not possible)

$ ./bin/tin1sthalf

enter word (50 char max): t_
1

$ ./bin/tin1sthalf

enter word (50 char max): _t
2

$ ./bin/tin1sthalf

enter word (50 char max): _t_
2

$ ./bin/tin1sthalf

enter word (50 char max): ___
-1

$ ./bin/tin1sthalf

enter word (50 char max): _T__
1

$ ./bin/tin1sthalf

enter word (50 char max): __t_
2

有很多很多方法可以解决这个问题。 如果他们遵守语言标准或 POSIX 标准(如果适用),那么没有人比其他人更有权利。 唯一的区别是效率之一。 当你学习编码时,你的重点应该放在让代码运行上,而不是过早地担心微优化。 一旦您的整个程序都可以运行,然后对其进行概要分析并担心此时的代码优化。

如果您有任何疑问,请告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM