C ++测试cstring数组中的特殊字符

Posted

技术标签:

【中文标题】C ++测试cstring数组中的特殊字符【英文标题】:C++ testing for special character in cstring array 【发布时间】: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;

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

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

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

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

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

【问题讨论】:

【参考方案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 数组的最佳方法背后的逻辑,就像我在我的问题。不过,还是有用的,谢谢

以上是关于C ++测试cstring数组中的特殊字符的主要内容,如果未能解决你的问题,请参考以下文章

在控制台中打印特殊字符 (C++/C#/SWIG)

C语言结构体值复制与字符数组值复制的比较测试

C语言fgets()函数(以指定长度读取文件中的字符,并存入字符数组变量中)

VB中的USB特殊字符(受病毒影响)目录数据

C中的自然排序 - “字符串数组,包含数字和字母”

521. 最长特殊序列 Ⅰ『简单』