繁体   English   中英

从C中的fscanf字符串中删除特殊字符

[英]Removing special characters from fscanf string in C

我目前正在使用以下代码扫描文本文件中的每个单词,将其放入变量中,然后在移动到下一个单词之前对其进行一些操作。 这工作正常,但我正在尝试删除所有不属于AZ / az.字符AZ / az. 例如,如果输入"he5llo" ,我希望输出为"hello" 如果我不能修改fscanf来执行它是否有办法在扫描后对变量执行此操作? 谢谢。

while (fscanf(inputFile, "%s", x) == 1)

你可以给这样的函数赋x 为了便于理解的第一个简单版本:

// header needed for isalpha()
#include <ctype.h>

void condense_alpha_str(char *str) {
  int source = 0; // index of copy source
  int dest = 0; // index of copy destination

  // loop until original end of str reached
  while (str[source] != '\0') {
    if (isalpha(str[source])) {
      // keep only chars matching isalpha()
      str[dest] = str[source];
      ++dest;
    }
    ++source; // advance source always, wether char was copied or not
  }
  str[dest] = '\0'; // add new terminating 0 byte, in case string got shorter
}

它会在原地经过字符串,复制与isalpha()测试匹配的字符,跳过并删除那些不匹配的字符。 要理解的代码,它认识到,C字符串只是重要的char数组,以字符串的字节值0标记结束。 另一个重要的细节是,在C数组和指针中有许多(不是全部!)方式相同的东西,所以指针可以像数组一样被索引。 此外,这个简单版本将重写字符串中的每个字节,即使字符串实际上没有改变。


然后是一个更全功能的版本,它使用作为参数传递的过滤器函数,并且只在str更改时才执行内存写入,并像大多数库字符串函数一样返回指向str指针:

char *condense_str(char *str, int (*filter)(int)) {

  int source = 0; // index of character to copy

  // optimization: skip initial matching chars
  while (filter(str[source])) {
    ++source; 
  }
  // source is now index if first non-matching char or end-of-string

  // optimization: only do condense loop if not at end of str yet
  if (str[source]) { // '\0' is same as false in C

    // start condensing the string from first non-matching char
    int dest = source; // index of copy destination
    do {
      if (filter(str[source])) {
        // keep only chars matching given filter function
        str[dest] = str[source];
        ++dest;
      }
      ++source; // advance source always, wether char was copied or not
    } while (str[source]);
    str[dest] = '\0'; // add terminating 0 byte to match condenced string

  }

  // follow convention of strcpy, strcat etc, and return the string
  return str;
}

示例过滤功能:

int isNotAlpha(char ch) {
    return !isalpha(ch);
}

示例调用:

char sample[] = "1234abc";
condense_str(sample, isalpha); // use a library function from ctype.h
// note: return value ignored, it's just convenience not needed here
// sample is now "abc"
condense_str(sample, isNotAlpha); // use custom function
// sample is now "", empty

// fscanf code from question, with buffer overrun prevention
char x[100];
while (fscanf(inputFile, "%99s", x) == 1) {
  condense_str(x, isalpha); // x modified in-place
  ...
}

参考:

读取int isalpha(int c); 手册:

检查c是否是字母。
返回值
如果确实c是字母,则值不为零(即,为真)。 否则为零(即假)

luser droog回答会起作用,但在我看来,它比必要的更复杂。

你可以试试这个简单的例子:

while (fscanf(inputFile, "%[A-Za-z]", x) == 1) {   // read until find a non alpha character
   fscanf(inputFile, "%*[^A-Za-z]"))  // discard non alpha character and continue
}

你可以使用isalpha()函数检查字符串中包含的所有字符

scanf系列函数不会这样做。 你必须循环遍历字符串并使用isalpha来检查每个字符。 并通过向前复制字符串的结尾“删除” memmove中的字符。

也许scanf毕竟可以做到。 在大多数情况下,如果无法匹配, scanf和friends会将任何非空白字符反馈回输入流。

此示例使用scanf作为流上的正则表达式过滤器。 使用* conversion修饰符意味着否定模式没有存储目标; 它只是被吃掉了。

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

int main(){
    enum { BUF_SZ = 80 };   // buffer size in one place
    char buf[BUF_SZ] = "";
    char fmtfmt[] = "%%%d[A-Za-z]";  // format string for the format string
    char fmt[sizeof(fmtfmt + 3)];    // storage for the real format string
    char nfmt[] = "%*[^A-Za-z]";     // negated pattern

    char *p = buf;                               // initialize the pointer
    sprintf(fmt, fmtfmt, BUF_SZ - strlen(buf));  // initialize the format string
    //printf("%s",fmt);
    while( scanf(fmt,p) != EOF                   // scan for format into buffer via pointer
        && scanf(nfmt) != EOF){                  // scan for negated format
        p += strlen(p);                          // adjust pointer
        sprintf(fmt, fmtfmt, BUF_SZ - strlen(buf));   // adjust format string (re-init)
    }
    printf("%s\n",buf);
    return 0;
}

我正在做一个类似的项目,所以你掌握得很好! 将单词划分为单独的部分。

空格不是cin每个单词的问题你可以使用a

 if( !isPunct(x) )

将索引增加1,并将该新字符串添加到临时字符串持有者。 您可以像字符串一样选择字符串中的字符,因此查找这些非字母字符并存储新字符串很容易。

 string x = "hell5o"     // loop through until you find a non-alpha & mark that pos
 for( i = 0; i <= pos-1; i++ )
                                    // store the different parts of the string
 string tempLeft = ...    // make loops up to and after the position of non-alpha character
 string tempRight = ... 

暂无
暂无

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

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