如何在读取文件时忽略c中的非字母字符

时间:2017-05-10 13:25:45

标签: c

我正在使用fscanf阅读文件。我想忽略非字母字符,如逗号,\,:和点。

这是我的代码:

FILE *fp;
fp = fopen(fl,"r");
char c[50];

while(fscanf(fp, "%s" ,c)!= EOF){
    linkLst(c);

}

fclose(fp);

如何逐字逐句地读取非字母字符?

{ 文件的一部分如下

与答案:

1)世界上最复杂的书面语言是什么? (提示:它 使用四个字符集。)(这个问题太容易了吗?)>>日本

2)什么语言的词汇主要来自阿拉伯语(大约70%, 我被告知),但使用罗马字母? (我想知道你在哪里找到的 答案!)>>马耳他

3)什么非浪漫语言在字母N上使用波浪号(〜)? >>爱沙尼亚语 }

4 个答案:

答案 0 :(得分:1)

您必须创建一个您读取的字符串副本,过滤掉非字母数字字符。

[Authorize, ApiExplorerSettings(IgnoreApi = true)] public class MyController : ApiController { public HttpResponseMessage method1() {/*...*/} [ApiExplorerSettings(IgnoreApi = false)] public HttpResponseMessage method2() {/*...*/} public HttpResponseMessage method3() {/*...*/} /*...*/ } 执行此操作后

scanf

答案 1 :(得分:0)

我将坚持“逐字逐句”阅读内容,而不是担心链接列表。

scanf函数系列使您能够进行简单的解析,因为scanf中有足够的功能,所以不需要逐个字符地执行。如果你想用char解析字符串char,那么只需使用fgets并执行你需要的解析。

我会坚持使用scanf,就像你正在使用的那样:

从包含以下内容的简单文件( foo.txt )开始

  

你好,你好吗?

并尝试扫描它:

坏例1:

/* NOTE: this code does NOT do what you want */
#include <stdio.h>

int main() {
    char foo[128];
    FILE *fp;
    fp = fopen("foo.txt", "r");
    do {
        sscanf(input, "%[A-Za-z0-9]", foo);
        fprintf(stderr, "foo: %s\n", foo);
    } while(1);
    return 0;
}

你得到一个无限循环打印hello,因为scanf被卡住了,并且在“你好”之后无法隐藏空格。

所以让我们添加一个munger:

#include <stdio.h>

int main() {
    char foo[128];
    char mung[128];
    char rv = 0;
    FILE *fp;
    fp = fopen("foo.txt", "r");
    do {
        rv = fscanf(fp, "%[A-Za-z0-9]%[^A-Za-z0-9]", foo, mung);
        if(rv == EOF)
            break;
        fprintf(stderr, "foo: %s\n", foo);
    }while(1);
}

所以munger会发布我们正在寻找的foo字符集中的所有内容(在{]中放置一个^作为第一个字符使scanf否定内容。

这将打印出来:

 foo: hello
 foo: there
 foo: how
 foo: are
 foo: you

现在,如果我们聪明,我们可以跳过mung变量的分配:

#include <stdio.h>

int main() {
    char foo[128];
    char rv = 0;
    FILE *fp;
    fp = fopen("foo.txt", "r");
    do {
        rv = fscanf(fp, "%[A-Za-z0-9]%*[^A-Za-z0-9]", foo);
        if(rv == EOF)
            break;
        fprintf(stderr, "foo: %s\n", foo);
    }while(1);
}

显然在我的例子中我假设foo小于128个字节。但是我们不知道,scanf(在2001年POSIX标准之后)允许你为以后必须free的字符串动态分配内存,所以:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char *foo;
    char rv = 0;
    FILE *fp;
    fp = fopen("foo.txt", "r");
    do {
        /* notice the & before foo, because fscanf will modify the pointer
         * variable itself and assign it a new pointer after allocating 
         * the space for the string
         */
        rv = fscanf(fp, "%m[A-Za-z0-9]%*[^A-Za-z0-9]", &foo);

        if(rv == EOF)
            break;

        fprintf(stderr, "foo: %s\n", foo);
        /* store the foo pointer somewhere for use and free it later,
         * if you are sticking it in a linked list, then you should 
         * free it whenever you free the corrosponding node.
         *
         * I am just going to free it here after printing it out
         */
        free(foo); 
    }while(1);
}

更新

正如BLUEPIXY所指出的,这不会消耗任何以非匹配字符开头的字符。等等,

  

))oops helo

将陷入(null)循环

这意味着我们需要对一个单独的操作进行修改,以便它能够解决问题:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char *foo;
    char rv = 0;
    FILE *fp;
    fp = fopen("foo.txt", "r");
    do {
        /* notice the & before foo, because fscanf will modify the pointer
         * variable itself and assign it a new pointer after allocating 
         * the space for the string
         */
        rv = fscanf(fp, "%m[A-Za-z0-9]", &foo);

        if(rv == EOF)
            break;

        /* foo would be null if scanf didn't read anything */
        if (foo) {
             fprintf(stderr, "foo: %s\n", foo);
        /* store the foo pointer somewhere for use and free it later,
         * if you are sticking it in a linked list, then you should 
         * free it whenever you free the corrosponding node.
         *
         * I am just going to free it here after printing it out
         */
             free(foo); 
        }


        rv = fscanf(fp, %*[^A-Za-z0-9]");

        if (rv == EOF) 
             break;

    }while(1);
}

(参见scanf(3))页面了解详情

答案 2 :(得分:-1)

使用 /// <summary> /// Method to simulate a throw SqlException /// </summary> /// <param name="number">Exception number</param> /// <param name="message">Exception message</param> /// <returns></returns> public static SqlException CreateSqlException(int number, string message) { var collectionConstructor = typeof(SqlErrorCollection) .GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, //visibility null, //binder new Type[0], null); var addMethod = typeof(SqlErrorCollection).GetMethod("Add", BindingFlags.NonPublic | BindingFlags.Instance); var errorCollection = (SqlErrorCollection)collectionConstructor.Invoke(null); var errorConstructor = typeof(SqlError).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof (int), typeof (byte), typeof (byte), typeof (string), typeof(string), typeof (string), typeof (int), typeof (uint) }, null); var error = errorConstructor.Invoke(new object[] { number, (byte)0, (byte)0, "server", "errMsg", "proccedure", 100, (uint)0 }); addMethod.Invoke(errorCollection, new[] { error }); var constructor = typeof(SqlException) .GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, //visibility null, //binder new[] { typeof(string), typeof(SqlErrorCollection), typeof(Exception), typeof(Guid) }, null); //param modifiers return (SqlException)constructor.Invoke(new object[] { message, errorCollection, new DataException(), Guid.NewGuid() }); } 函数过滤掉每个字符。

isalpha

并且正确的函数while (fscanf(fp, "%s", c) != EOF) { char* ptr = c; while (*ptr) { if (isalpha(*ptr)) { linkLst(*ptr); } ptr++; } } 接受逐个字符而不是字符指针。

linkLst作为参数必须linkLst,您可以这样做:

char *

答案 3 :(得分:-1)

包含标题#include <ctype.h>,其中包含函数isalpha(char c),如果true是字母字符,则返回c

if ( isalpha(c))
{
     // do what you wanna do
}
else 
{
     // ignore
}

否则,您可以使用ASCII table。像使用int一样使用字符并进行比较。例如,要检查char是否是字母和大写字母,您可以执行以下操作:

if ( c < 66 && c > 90)
{
    // do what you wanna do
}
else 
{
    // ignore
}

如果c是一个标签,那么就像这样循环:

for (int i = 0; i < sizeof(c); i++) // Then use c[i] to access to char inside it
{
    if (c[i] < 66 && c[i] > 90) // or if (isalpha(c[i])
    {
        // do what you wanna do
    }
    else 
    {
       // ignore
    }
}

你也可以写:

if (c[i] < 'A' && c[i] > 'Z') 

感谢ASCII表,'A' == 66'Z' == 90