【问题标题】:C++ testing for special character in cstring arrayC ++测试cstring数组中的特殊字符
【发布时间】:2011-07-30 10:26:00
【问题描述】:

我有一个 C 字符串数组:

char test[6] = {'\n', 't', 'e', 's', 't', '\0'}

我想测试字符串是否以空白字符(\n、\t、\r)开头,如果是,则重新排列数组,以便将非空白字符移到数组的前面并对于每个需要删除的空白字符,将 cstring 缩短 1。

所以如果我从一个看起来像这样的字符串开始:

\n, \t, t, e, s, t, \0
or
\r, t, e, s, t, \0

在函数之后,两个数组将如下所示:

t, e, s, t, \0
t, e, s, t, \0

我有两个问题。我的第一个是我对特殊字符的条件测试没有正常工作

int idx = 0;
if (test[idx] != '\n' || test[idx] != '\r' || test[idx] != '\t')
    return;

即使它确实以这些特殊字符之一开头也会返回。

不过,这似乎也需要进行重大改进。

然后,我不知道如何剪辑字符串。例如,如果字符串以空格字符开头,我基本上需要删除该字符,将其他字符向上移动,然后每次将字符串缩短一个。

基本上,我正在为如何做到这一点的逻辑而苦苦挣扎。

非常感谢任何和所有的帮助。提前致谢!

【问题讨论】:

    标签: c++ string logic


    【解决方案1】:

    为什么不直接增加指针直到找到非空白字符?

    char* cstr = test;
    while (*cstr && (*cstr == '\n' || *cstr == '\r' || *cstr == '\t'))
        ++cstr;
    

    【讨论】:

    • 如果test 实际上是一个数组,您将无法更改其地址。
    【解决方案2】:

    您所写的测试是检查字符是否不等于任何空白字符。您需要检查它是否不等于所有这些。你想要:

    int idx = 0;
    if (test[idx] != '\n' && test[idx] != '\r' && test[idx] != '\t')
        return;
    

    然后,假设 idx 是第一个非空白字符的索引,或者是空终止符,您可以像这样缩短字符串:

    int i;
    for (i = 0; test[idx+i] != '\0'; i++)
        test[i] = test[idx+i];
    test[i] = '\0';
    

    正如其他人所说,使用isspace() 和指针可以通过更优雅的方式完成所有这些操作,但这应该可以为您提供基本概念。

    【讨论】:

      【解决方案3】:

      首先,改用isspace,它会让代码更简单,并确保代码找到你没有想到的空白字符。

      其次,如果您必须使用char[] 或必须实际删除空格,那么您将不得不做更多的工作。如果您只需要一个指向字符串开头的指针,那么它会让生活变得更轻松。字符仍会在内存中,但如果您使用指针,它们将不会出现在字符串的开头。

      char test[] = "\ntest";
      char *test_ptr = test;
      while (*test_ptr && isspace(*test_ptr)) {
          ++test_ptr;
      }
      /*test_ptr now points to the first non-whitespace character in test, or the NULL character at the end of the string if it was all whitespace.*/
      

      如果您在 char 数组本身的开头需要此字符串,则可以在上述代码之后使用 memmove 将字符串移过来(strcpy 将不起作用,因为范围重叠):

      /* to be placed after block of code above */
      memmove(test, test_ptr, strlen(test)-(test_ptr-test)+1); /* +1 for NULL not automatically copied with memmove */
      /* test[0] is now the first non-whitespace character or NULL */
      

      或者既然你使用的是C++,你可以走std::string路线:

      std::string test = "\ntest";
      size_t start_pos = test.find_first_not_of("\r\n\t");
      if (start_pos != std::string::npos) {
          test = test.substr(start_pos, std::string::npos);
      } else {
          test = "";
      }
      //test now contains no whitespace in the beginning
      

      【讨论】:

      • 我确信这是最好的方法,但这不是编写代码的最佳方法,而是要找出重新排列 cstring 数组的最佳方法背后的逻辑,就像我在我的问题。不过,还是有用的,谢谢
      猜你喜欢
      • 2019-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多