Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 是否有一种方法可以轻松检查字符串是否填充了空格/制表符/下线,而没有其他内容?_C_String - Fatal编程技术网

C 是否有一种方法可以轻松检查字符串是否填充了空格/制表符/下线,而没有其他内容?

C 是否有一种方法可以轻松检查字符串是否填充了空格/制表符/下线,而没有其他内容?,c,string,C,String,我正在创建一个程序,从文件中逐行读取数据。我想实现一个检查,在读取行并将其存储在字符串中之后,检查它是否有任何一个字符不是空格/制表符/下线。因此,基本上我要做的是跳过这一行,如果整行没有空格/制表符/下线以外的内容,就不存储它。使用strpbrk搜索字符串中的字符。返回指向第一次出现位置的指针,如果未找到,则返回NULL 让我们调用字符串缓冲区,一次处理一个字符 char *tmp = buffer; // give tmp the address of the buffer's first

我正在创建一个程序,从文件中逐行读取数据。我想实现一个检查,在读取行并将其存储在字符串中之后,检查它是否有任何一个字符不是空格/制表符/下线。因此,基本上我要做的是跳过这一行,如果整行没有空格/制表符/下线以外的内容,就不存储它。

使用strpbrk搜索字符串中的字符。返回指向第一次出现位置的指针,如果未找到,则返回NULL


让我们调用字符串
缓冲区
,一次处理一个字符

char *tmp = buffer; // give tmp the address of the buffer's first character.

// Assuming you have bool defined.
// If you don't, just switch this with whatever you prefer to use for bools.
bool bHasValidChar = false;

while(*tmp){
    if(*tmp != ' ' && *tmp != '\t' && *tmp != '\n'){
        // Cool, this character is not whitespace
        bHasValidChar = true;
        break;
    }else{
        // The character is whitespace
        // Move on and test the next character
        tmp++;
    }
}

if(bHasValidChar){
    // Contains non-whitespace. Do something.
}else{
    // Str is only whitespace. Do something.
}
如果您没有bool(如果您使用的是旧版本的C,则可能没有bool),那么请使用int而不是bool(1&0代替true和false),或者您喜欢的任何东西

希望这有帮助


注意:这是从我的手机上打下来的,所以没有经过测试。对于我的帖子和代码中的任何错误,我深表歉意,但希望这能让您从正确的方向开始。

3种方法:查看是否存在任何非空白

char nws[2];
if (sscanf(buf, "%1s", nws) == 1) foo(buf);
else skip();  // all white-space

// or if code wants to use specific ws characters
if (buf[strspn(buf, " \t\r\n")] != '\0') skip();

int Interesting(const char *s) {
  // Take advantage that the null character is not a white-space
  while (isspace((unsigned char) *s)) {
    s++;
  }
  return *s;
}

基本上,您需要在字符串上循环,直到结束或找到一个不属于“允许的字符”的字符:

如果您希望成为未来某些WTF的原因(维护代码的人也可能是您未来的自己),请添加以下内容以提高速度:

char only_whitespace(char const * str /* NULL terminated */) {
  for (; *str; ++str) {
    if ((*str >> 6) || (*str & 16)) {
      return 0;
    }
    switch (*str) {
      case 32: /* space */
      case  9: /* TAB */
      case 10: /* line feed */
      case 13: /* carriage return, windows... */
        break;
      default: return 0;
    }
  }
  return 1;
}
原因:

0b00100000 = 32
0b00001001 =  9
0b00001010 = 10
0b00001101 = 13

0b00010000 = 16

等一下…

我正在创建一个程序,从文件中逐行读取数据。[……]

如果您正在逐行阅读,那么您的行中将不会有任何“行尾”字符。这就是逐行阅读的要点。因此,您只需要检查空格或制表符


有了这个,我们也会变得疯狂:

0b00100000 = 32 (space)
0b00001001 = 9 (tab)
---------- bitwise or
0b00101001
---------- bitwise not
0b11010110 = 0xD6 (mask of bits that must not be set)
现在,假设采用64位体系结构,我们可以将该位掩码复制8次,并使用它对字符串进行快速“预扫描”,如果我们预期字符串的比率很高,而不仅仅是由空白字符组成,则可以加快检查速度。虽然我们之前应该知道长度,否则获得长度可能会破坏任何性能增益:

char only_whitespace_with_prescan64(char const * const str /* one line */, size_t length) {
  uint64_t const * cursor = (uint64_t const *) str;
  uint32_t mask32 = 0xD6 | (0xD6 << 8) | (0xD6 << 16) | (0xD6 << 24);
  uint64_t mask64 = ((uint64_t) mask32) << 32 | mask32;
  for (; length != 0; --length, ++cursor) {
    if (*cursor & mask64) {
      return 0;
    }
  }
  return only_whitespace(str);
}
char-only\u-whitespace\u和\u-prescan64(char-const*const-str/*one-line*/,size\u-t-length){
uint64常量*游标=(uint64常量*)str;

uint32_t mask32=0xD6|(0xD6循环遍历字符串中的字符,并测试每个字符是否与问题中提到的字符不同……显示您已尝试的内容。实际上,每当您要检查一行是否包含任何不被视为空格的字符时,在最坏的情况下,您必须迭代整个字符串。@tchelidzeC和C++不。BTW您的测试不考虑标签。您可以尝试<代码> STRSPN < /Cord>。它返回了所提供的集合中的第一个字符的索引。是的,有一个方法。但是在ASCII中没有代码< EOL>代码>字符。HMM我甚至不知道函数存在。但是,OP要检查是否有WHI以外的字符。tespace。如果OP想要检查空白,这将非常有用,但除非OP向此函数传递每个非空白字符的列表,否则此函数将无法按照OP的要求工作。您正在执行否定检查。如果找到不需要的字符,则拒绝。如果(!strpbrk(buffer,“\t\n”))存储(buffer);…检查它是否有任何一个字符不是空格/制表符/下线。根据OP所说的,我相信他想检查确保一个字符串至少包含一个非空白字符。基于此,我相信他说的像
Hello,World!
这样的字符串是完全可以接受的,尽管事实上这个string包含一个空格。也许我误解了OP。哦,我现在明白你在做什么了。谢谢你用一个例子发布第二条评论。我错了。为什么不直接使用
isspace()
?但实际上没有编码服务。您提供完整的代码并不是一件好事。虽然代码可能需要修复,但我没有检查,这个想法是最好的。@Olaf,我已经很久没有用C编写代码了,所以我完全忘了函数存在xD。谢谢您的建议。使用
isspace()肯定会更干净,更容易阅读。当然,使用<代码>案例> t′/代码>而不是<代码>案例9 < /代码>等更容易理解。考虑“代码>”/>代码>而不是32,等等。@ CHUX。通常我会使用字符文字来进行类似的事情,但在这里选择它们来理解ASCII和T的依赖性。他说:“优化”(:D)。不过,有了注释,这段代码应该足够清晰。
char only_whitespace_with_prescan64(char const * const str /* one line */, size_t length) {
  uint64_t const * cursor = (uint64_t const *) str;
  uint32_t mask32 = 0xD6 | (0xD6 << 8) | (0xD6 << 16) | (0xD6 << 24);
  uint64_t mask64 = ((uint64_t) mask32) << 32 | mask32;
  for (; length != 0; --length, ++cursor) {
    if (*cursor & mask64) {
      return 0;
    }
  }
  return only_whitespace(str);
}