我目前正在使用以下代码扫描文本文件中的每个单词,将其放入变量中,然后在移动到下一个单词之前对其进行一些操作。这工作正常,但我正在尝试删除不属于A-Z / a-z.
的所有字符,例如,如果输入了"he5llo"
,我希望输出为"hello"
。如果我无法修改fscanf
来执行此操作,那么在扫描后是否可以对变量执行此操作?感谢。
while (fscanf(inputFile, "%s", x) == 1)
答案 0 :(得分:3)
您可以将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
...
}
参考:
检查c是否是字母 返回值:
如果确实c是字母,则该值不为零(即,为真)。否则为零(即假)
答案 1 :(得分:1)
luser droog answer会起作用,但在我看来,它比必要的更复杂。
你可以试试这个简单的例子: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
}
答案 2 :(得分:0)
您可以使用isalpha()
函数检查字符串
答案 3 :(得分:0)
scanf
家庭功能不会这样做。你必须循环遍历字符串并使用isalpha
来检查每个字符。通过向前复制字符串的结尾,使用memmove
“删除”该字符。
毕竟,scanf
也许可以做到。在大多数情况下,scanf
和朋友会将任何非空白字符反馈回输入流,如果它们无法匹配的话。
此示例使用scanf
作为流上的正则表达式过滤器。使用*
转换修饰符意味着否定模式没有存储目标;它只是被吃掉了。
#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;
}
答案 4 :(得分:0)
我正在做一个类似的项目,所以你掌握得很好!将单词划分为单独的部分。
空格不是每个单词cin的问题 你可以使用
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 = ...