【问题标题】:fscanf() to read in only characters with no punctuation marksfscanf() 只读取没有标点符号的字符
【发布时间】:2015-09-06 00:57:14
【问题描述】:

我想从文本文件(在命令行中指定为参数的名称)中读取一些单词(在本例中为前 20 个)。当下面的代码运行时,我发现它也需要带有字符的标点符号。

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

int main(int argc, char * argv[]){
int wordCap = 20;
int wordc = 0;
char** ptr = (char **) calloc (wordCap, sizeof(char*));
FILE *myFile = fopen (argv[1], "r");
if (!myFile) return 1;
rewind(myFile);
for (wordc = 0; wordc < wordCap; wordc++){
  ptr[wordc] = (char *)malloc(30 * sizeof( char ) );
  fscanf(myFile, "%s", ptr[wordc]);
  int length = strlen(ptr[wordc]);
  ptr[wordc][length] = '\0';
   printf("word[%d] is %s\n", wordc,  ptr[wordc]);
}
 return 0;
}

当我通过这句话时:“有一次狮子睡着了,一只小老鼠开始在他身上跑来跑去;”,“他”后面会跟一个分号。

我把fscanf()改成了fscanf(myFile, "[a-z | A-Z]", ptr[wordc]);,它把整个句子当成一个词。

如何更改它以产生正确的输出?

【问题讨论】:

  • 您指定的扫描集接受小写字母、大写字母、空格和竖线符号。尤其不要包括空格;你也不是真的想要管道,尽管它会造成更少的伤害。不要忘记您必须使用其他东西来读取终止扫描集的字符。

标签: c io scanf


【解决方案1】:

您可以接受分号,然后将其删除,如下所示:

将单词存储在 ptr[wordc] 中之后:

i = 0;
while (i < strlen(ptr[wordc]))
{
    if (strchr(".;,!?", ptr[wordc][i])) //add any char you wanna delete to that string
        memmove(&ptr[wordc][i], &ptr[wordc][i + 1], strlen(ptr[wordc]) - i);
    else
        i++;
}
if (strlen(ptr[wordc]) > 0) // to not print any word that was just punctuations beforehand
    printf("word[%d] is %s\n", wordc,  ptr[wordc]);

我没有测试过这段代码,所以可能有错别字。

或者你可以切换

fscanf(myFile, "%s", ptr[wordc]);

fscanf(myFile, "%29[a-zA-Z]%*[^a-zA-Z]", ptr[wordc]);

只捕获字母。 29 限制字长,因此您不会溢出,因为您只为 30 个字符分配大小

【讨论】:

  • 谢谢。这绝对是一种策略,但我正在寻找替换 %s 的行,或者证明它不可能的答案。
  • @JiajuShen 我补充了一些信息
猜你喜欢
  • 2017-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-04
相关资源
最近更新 更多